# Overview

## Protocol Introduction

The *Mezzanine* protocol is a set of smart contracts that enables any individual(s) to start and maintain an on-chain organization with minimal costs and effective shareholder governance.  Decentralized Autonomous Organizations (DAOs) have enabled fair and democratic governance over on-chain protocols.  However, they are often ineffective.  The lack of organizational structure has created a vacuum in which duties, roles, and a decisional hierarchy are, for the most part, unclear.  In contrast, traditional, off-chain organizations are costly to maintain with little transparency.  For nearly every substantial action, a series of lawyers, accountants, and other experts are needed.&#x20;

The Mezzanine protocol aims to mediate these two extremes.  The protocol simultaneously enables a clear organizational structure for DAOs while effectively reducing the costs associated with maintaining an organization.  In place of litigation, smart contracts, themselves, are used to provide clear, executable logic for shareholder governance, equity financing, organizational structure, etc.&#x20;

Most notably, Mezzanine introduces a [*capital stack*](/protocol/capital-stack) and [*shareholder governance.*](/protocol/shareholder-governance) The former provide novel financial tools to onchain organizations, such as preferred shares and debt that are directly tied to the organization itself. The latter provides governance tools premised on delegated accountability.&#x20;

Most DAOs are limited to spending money, receiving money, and making clunky decisions. Mezzanine companies enjoy a much more robust set of features:

1. Tracks and enforces economic rights, including debt and equity
2. Tracks and enforces governance rights, like the shareholders' choices for the board of directors
3. Enables delegation through the creation of departments and sub-departments&#x20;
4. Easy augmentation of modules for spending assets and generating revenues

## Protocol Overview

The Mezzanine protocol creates a simple and scalable organizational structure for running companies. Every company has a treasury that is run by a *Board of Directors.* A treasury can create any number of departments and sub-departments with granular abilities. Board directors are selected through shareholder governance, ensuring proper checks and balances. All Mezzanine companies have a capital stack that automatically tracks all economic claims on the organization, like liquidation preference, debt obligations, and vesting shares. A Mezzanine company can easily add new features and functionalities by adding additional modules for spending, billing, vesting, raising money and more.&#x20;

## Organizational Structure

Spending and access control in Mezzanine is hierarchical and follows a tree-like data structure. A company built using the Mezzanine Protocol has three critical components to its structure: [*Treasury*](/protocol/treasury-and-departments), [*Departments*](/protocol/treasury-and-departments/departments), and [*Modules*](/protocol/modules).&#x20;

The [*Treasury* ](/protocol/treasury-and-departments)of a company lies at the root of the company's organizational tree. The treasury signers act as the Board of Directors of the organization, granting powers and allowances to departments and modules. The treasury holds the vast majority of a company's assets at all times.

[*Departments*](/protocol/treasury-and-departments/departments) are created under the treasury or another department. They're given allowances to spend money and granted rights to control modules. Departments can add *modules* and additional sub-departments.

[*Modules*](/protocol/modules) are bespoke, standalone contracts designed to support companies and departments.  Technical teams (and 3rd party developers) can easily create new modules with limitless possibilities.

## Enforcing Economic Rights

Each Mezzanine company is deployed with a [capital stack](/protocol/capital-stack). The capital stack tracks and enforces the economic rights of varoius stakeholders. It is comprised of instruments like [common shares](/protocol/capital-stack/share-classes), [preferred shares](/protocol/capital-stack/share-classes), and [debt](/protocol/capital-stack/debt). From the capital stack, one can create a crystal clear picture of a company's ownership structure, liquidation preference, debt obligations, and cap table. The capital stack dictates which stakeholders receive assets in the event of a company's liquidation, recapitalization, or acquisition. Shares are also used in the governance of the company.&#x20;

## Shareholder Governance

Shareholder governance is predicated on *shareholder supremacy*, meaning that shareholders should hold ultimate control of a company. Among other things, shareholder governance selects the board of directors.&#x20;

Governance is designed to be flexible to meet an organization's needs at any given state of maturity. In the first version of Mezzanine, there are a few governance modules available: [Startup Governance](/protocol/shareholder-governance#startup-governance), [Share Class Governance](/protocol/shareholder-governance#share-class-governance), and [Late Stage Governance](/protocol/shareholder-governance#late-stage-governance).&#x20;

Shareholder governance assumes that most shareholders are relatively naive and uninvolved, so it limits their required participation to a handful of key decisions. Most day-to-day responsibilities are delegated to the board of directors.

Shareholder governance is responsible for a few primary actions:

* Managing an organization's board of directors
* Changing the shareholder governance structure
* Authorizing new shares
* Approving liquidation or acquisition

## Smart Company Modules

A set of module-like contracts easily augment any Mezzanine company:

* [**Governance Modules**](/protocol/shareholder-governance): dictates the logic of how board members should be added and removed from the board of directors
* [**Capital Stack**](/smart-contracts/source-code/core/capitalstack)**:** dictates the distribution of assets during a company's liquidation, recapitalization, merger, or acquisition
* [**Payroll Manager**](/protocol/modules/payroll)**:** manages the cash and equity compensation for a company's employees
* [**Billing**](/protocol/modules/billing):  companies can easily track request payments, track outstanding bills, and categorize revenues
* [**Equity Financing**](/protocol/modules/equity-financing-module)**:** responsible for raising capital in exchange for ownership of the company
* [**Delegate Registry**](/smart-contracts/source-code/core/delegateregistry)**:** manages the delegates of shareholders, such that their voting power can be given to another individual(s)
* [**Token Timelock**](/smart-contracts/source-code/core/tokentimelock)**:** manages the vesting and unlock schedule of shares


# Treasury & Departments

A company's treasury sits at the root of the Mezzanine protocol.  It is, itself, a *multi-signature wallet.*  The signers of the Treasury contract are the *Board of Directors* of the organization. &#x20;

The Treasury contract is responsible for holding the vast majority of a company's assets at any given point in time.  Similar to how access control in Mezzanine is hierarchical, the *spending* and *allowances* of assets are also hierarchal.   An *allowance* is the amount that another address can spend of an ERC20 on behalf of another address.  For example, if Alice gives Bob an allowance of 100 USDC, Bob can spend up to 100 of Alice's USDC on her behalf. &#x20;

Access control in Mezzanine is hierarchical and follows a [tree-like data structure](https://en.wikipedia.org/wiki/Tree_\(data_structure\)), which in turn is similar to a traditional organizational hierarchy.  At the *root* of the tree lies the Treasury.  The signers of the Treasury, which, again, is a multi-signature wallet, are the company's *board of directors*.  As such, they can perform actions that the signers of departments cannot.  For example, they can issue authorized shares, add and remove departments or modules at any part of the organizatio&#x6E;*,* manage the signers of *any* department, etc.

Treasuries and departments in Mezzanine are multi-signature wallets.  Specifically, they are Safe (formerly Gnosis Safe) wallets.  These types of wallets require cryptographic *signatures* from a set of *signers* to execute a transaction.  The number of required signatures to execute a transaction is called the *threshold* and can be different than the total number of signers. &#x20;

## Company Creation&#x20;

When making a Mezzanine company, five variables must be decided:&#x20;

1. **A company name:** all company names are unique
2. **The company's symbol:** the company's symbol functions the same as a ticker for publicly traded equities. All company symbols are unique
3. **The company's denomination asset:** the asset that is used to pay employees, determine if the company is at risk of bankruptcy, and distributed during a company's liquidation
4. **An initial number of authorized common shares**
5. **The company's board of directors:** who and how many people are set as directors&#x20;
6. **A threshold:** the number of directors needed to make a governance decision

Below is an example of the *most simple* Mezzanine company:

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FmceqQSJsTQOoaPvyq91R%2Fsimplest-mezz-company.png?alt=media&amp;token=06ab4442-ed0b-4f6b-9c0a-c64d60b2ffa2" alt=""><figcaption></figcaption></figure>

Mezzanine's smart contracts can be used by *anyone* and are not limited to a single interface.  Any group of individuals may choose to use our SDK to build an interface upon the Mezzanine protocol.  For example, a team building a decentralized exchange using Mezzanine may want to enable shareholder governance within their interface.  They can seamlessly accomplish this via our SDK.


# Signers & Access Control

The Mezzanine Protocol strives for complete mediation for access control between different actors within a company. A company in the Mezzanine Protocol is made up of its *Treasury*, [*Departments*](/protocol/treasury-and-departments/departments), and [*Modules*](/protocol/modules).

Access control in Mezzanine is hierarchical and follows a [tree-like data structure](https://en.wikipedia.org/wiki/Tree_\(data_structure\)), which in turn is similar to a traditional organizational hierarchy.  At the *root* of the tree lies the Treasury.  The signers of the Treasury, which, again, is a multi-signature wallet, are the company's *board of directors*.  As such, they can perform actions that the signers of departments cannot.  For example, they can issue authorized shares, add and remove departments or modules at any part of the organizatio&#x6E;*,* manage the signers of *any* department, etc.

Below is a simple example of the organizational structure of a larger Mezzanine company:

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FbM6P2aUagVkCdbSmbpiN%2Fmezz-company-organizational-relationships.png?alt=media&amp;token=e8b22fb9-55b3-4e86-9287-0c0e6c1ad327" alt=""><figcaption></figcaption></figure>

The relationships in a tree data structure are commonly described via familial relationships.  For example, the *parent* of the Finance Department in the above diagram is the Treasury.  The *children* of the Finance Department are the Billing Department and the Subscription Module.  An *ancestor* is a node that can be reached via repeated processing of child-to-parent relationships.  For example, the Treasury is an *ancestor* of the Billing Department.  Conversely, the Billing Department is a *descendant* of the Treasury. &#x20;

The following are truisms about access control in Mezzanine Organizations:

* The treasury and a department can insert new modules or departments as *children*
* An ancestor can manage the signers and threshold for any *descendant* departments&#x20;

For further demonstration, the Billing Department in the above example can insert new *modules* or *children* below itself.   However, the Finance Department and Treasury are also able to do this on the Billing Department's behalf. &#x20;

The creation and insertion of new modules in Mezzanine is standardized, enabling technical teams to easily create and develop those that best suit their needs.  Moreover, 3rd party teams can easily sell modules as products to other Mezzanine companies.  For example, a team may develop a subscription module, which represents unique recurring revenues via an ERC721.  The team could then subsequently sell this module to other teams across the protocol. &#x20;

Due to the bespoke nature of modules, truisms regarding them are impossible to enforce.  However, we encourage teams to build modules with the following in mind:&#x20;

*Any admin-like functionality should be executable by an ancestor*

Building upon the subscription module example, assume that each instance of a subscription module requires access control to determine pricing.  Pricing should then be set by any of its ancestors, not just its parent. &#x20;

Unlike departments, a treasury *does not* have a parent.  Rather, its signers (i.e. the board of directors) are managed by a *shareholder governance* process.  There are [three different governance structures](/protocol/shareholder-governance) the organization can choose.  Through shareholder governance, board members can be added, removed, or swapped. &#x20;

Modules and departments can also be removed as children at will with a couple of exceptions:

* A treasury can only have a single *Equity Financing Module* and it cannot be removed
* The *Equity Financing Module* cannot be inserted as a child by a department

## Multi-Signature Wallets

Multi-signature wallets require a minimum threshold of approval to complete an action. This is gererally referred to as "n of m" approval.&#x20;

For example, Alice, Bob, and Charlie are the signers of a multi-signature wallet with a threshold of two.  Therefore, only two of them are required to sign to be able to execute an arbitrary transaction.  Signers of Safe Wallets are not limited to [Externally Owned Accounts ](https://ethereum.org/en/developers/docs/accounts/)(EOAs) but can also be smart contracts, such as[ EIP-4337 ](https://eips.ethereum.org/EIPS/eip-4337)Smart Wallets. &#x20;

*Learn more about Safe* [*here*](https://docs.safe.global/getting-started/readme)*.*

As multi-signature wallets, departments and treasuries can interact with any other smart contract.  However, it is recommended to interact solely with *established* protocols outside of Mezzanine instead of novel ones, which are more prone to exploitation.  For example, assets stored in the Treasury can be lent on a decentralized lending-and-borrowing protocol, such as [AAVE](https://aave.com/), to earn a yield.  Similarly, they can be swapped on decentralized exchanges, such as [Uniswap](https://uniswap.org/), for other assets, which can then in turn be used to pay contractors.  However, once assets leave Mezzanine's smart contracts, there is no means by which the Mezzanine team can prevent funds from being lost in the event of an exploit. &#x20;


# Spending Funds & Allowance

Similar to how access control in Mezzanine is hierarchical, the *spending* and *allowances* of assets are also hierarchal.   An *allowance* is the amount that another address can spend of an ERC20 on behalf of another address.  For example, if Alice gives Bob an allowance of 100 USDC, Bob can spend up to 100 of Alice's USDC on her behalf. &#x20;

ERC20 allowances are used in Mezzanine to enable departments and their *descendants* to spend funds *directly* from the Treasury.  Take the following example of Mezzanine company, *Foo*:

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FxQE7puBX6yQXwlgOot49%2Forganizational-spending-example-1.png?alt=media&amp;token=368d0100-15c4-46b7-be88-fa09b27171c9" alt="" width="563"><figcaption><p>Simple Example of Allowances in Mezzanine</p></figcaption></figure>

In the above example, *Foo's* Treasury contains 1,000 USD, and its Finance Department has an allowance of 1,000 USD.  The Finance Department can spend this at its discretion.  Notably, the Treasury can also set allowances *higher* than its current balance. In the above example, the Billing Department has an allowance of  2,000 USD of *Foo*'s Treasury even though the treasury only contains 1,000 USD. When the allowance is greater than the funds available, the child can only spend up to the amount available to the ancestor.&#x20;

Setting an extremely high allowance may be useful when a department needs a highly variable amount of funds as working capital.  However, setting a high allowance should be used with caution, and the signers of the department should be trusted to use those funds wisely.

Under the Finance Department is a Sales Department, which can spend up to 500 USD at its discretion.  Spending funds transfers funds *down the organization*, decreasing the allowances of its ancestors by the amount.  Let's assume that *Foo's* Sales Department spends all 500 of its USD allowance:

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2F6wuitMYKNaFq4OWvB8Ta%2Forganizational-spending-example-2.png?alt=media&amp;token=afca9e32-66a1-468d-91af-8c6428492e5f" alt="" width="563"><figcaption><p>Simple Example of Spending in Mezzanine</p></figcaption></figure>

The Sales Department's spending of 500 USD decreases the Treasury Contract's balance by 500.  Notably, the allowances of *both* the Finance Department and Sales Department decreased by 500. All modules and departments in Mezzanine have access to this hierarchic spending. &#x20;


# Departments

{% hint style="info" %}
For technical documentation, see [departments](/smart-contracts/source-code/core/department)
{% endhint %}

## Overview

Departments in Mezzanine are analogous to departments in a typical organization. They are used to separate different business units to better delegate tasks related to the operation of the organization.  Similar to a company's treasury, departments in Mezzanine are multi-signature wallets.  Specifically, they are *Safe (formerly Gnosis Safe)* wallets. &#x20;

Departments, like the organization's treasury, can have sub-departments, their sub-departments can have sub-departments, and so on.  The number of departments in an organization is bespoke and determined by its needs. &#x20;

Access control of departments resembles a tree-like data structure.  A department can manage any of its sub-department's signers, its sub-department's sub-departments, and its sub-department's modules.  Access to the organization's treasury's funds behaves similarly: to spend funds, a department must have *approvals* from its *parent,* its parent must have approval from its parent, and so on.  A department must approve its respective sub-departments and modules for them to access funds. &#x20;

As multi-signature wallets, departments can spend funds at their discretion.  They can interact with any other smart contract outside of the Mezzanine system, such as Uniswap, OpenSea, among others. &#x20;

Giving spending powers comes with risks.  To address this, a department's *ancestors* will be able to block its multi-signature functionality from interacting with specified contracts or specified functionality within contracts.  For example, a parent of a department can prevent a department from interacting with all Uniswap contracts, or the parent could disable the department from borrowing on AAVE while maintaining the ability to lend.  This type of enforcement can be completed in one of two ways:

1. A whitelist&#x20;
2. A blacklist

By default, departments are created with a *blacklist* on Mezzanine's interface.  A department will not be able to interact with any specified functions or contracts on this list.  This list is managed by the department's *parent*.  Conversely, this blacklist can be swapped for a *whitelist* by the department's ancestors.  Departments subjected to a whitelist will not be able to interact with *any* contract, *including itself*, via its multi-signature functionality until it is whitelisted by its parent.  This includes ERC20 smart contracts, meaning departments subjected to a whitelist will not be able to transfer funds outside of the Mezzanine protocol until they are permitted to do so.  Under certain circumstances, such as during a company's recapitalization, a department's whitelist or blacklist will be controlled by shareholders. &#x20;

We recommend that the *threshold* of the department's multi-signature functionality be at least two.  The signers should also be trusted individuals.  However, these suggestions are not enforced on-chain. &#x20;

The majority of departments in larger Mezzanine organizations will solely be able to:

* Spend and transfer funds
* Add other departments and modules as *children*

Their standalone functionality is notably limited and stems from smart contract size limits.  However, the insertion of modules enables a plethora of functionality. &#x20;


# Capital Stack

{% hint style="info" %}
For technical documentation, please see [CapitalStack](/smart-contracts/source-code/core/capitalstack)
{% endhint %}

A *Capital Stack* refers to the variety of economic claims against a company's assets and cashflows. It also refers to the mix of financing that a company uses to fund its operations and growth. The capital stack is composed of different forms of debt and equity.  The capital stack dictates which stakeholders receive assets in the event of a company's liquidation, recapitalization, merger, or acquisition. &#x20;

Each Mezzanine company is deployed with a capital stack.  A Mezzanine capital stack is comprised of *seniority levels* and *assets.*  Seniority levels dictate the prioritization of  the payments to stakeholders during a company's liquidation, recapitalization, etc.  Each seniority level can contain up to 15 assets, and a company can have up to 15 seniority levels.

Both seniority levels and assets are characterized by an *asset class*.  There are three different types of asset classes in Mezzanine:&#x20;

1. Common Equity
2. Preferred Equity
3. Debt

The following truisms exist for every capital stack in Mezzanine:

1. A *debt* seniority level cannot be inserted below a *common equity* or *preferred equity* seniority level
2. A *preferred equity* seniority level cannot be inserted below a *common equity* seniority level nor above a *debt* seniority level
3. A *common equity* seniority level  cannot be inserted above a *preferred equity* or *debt* seniority level&#x20;

Mezzanine assets cannot be inserted into a seniority level that does not match their asset class.  For example, only Preferred and Common shares can be inserted into common equity and preferred equity seniority levels, respectively. &#x20;

Below is an example of a capital stack in Mezzanine:

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FpscY24b55U4Meu7vaGA9%2Fsimple-mezz-capital-stack.png?alt=media&amp;token=bee136f2-d929-4d8e-9564-ed7d088abda4" alt="" width="330"><figcaption></figcaption></figure>

In the above example, debt asset, *F,* would be paid out before *D* and *E* in the event of a company's liquidation, while *D* and *E* would be paid out before the liquidation preferences of *B* and *C*. &#x20;

Unlike departments and modules, developers cannot add custom assets to the capital stack. Third-party creations are likely prone to potential errors that conflict with other functions, like liquidation. Moreover, untested asset types may lead to unpredictable methods of exploitation.

Each Mezzanine company is created with a single Common Equity seniority level that contains its common shares.  This remain as the entire capital stack until the company decides to add to it. &#x20;

## Share Classes

All shares represent assets that have equity-like claims to underlying assets. Shareholders also control governance. There are two types of share classes in Mezzanine: common shares and preferred shares.  There are a few notable differences between the two:

* Each Mezzanine Company can have only a *single* set of common shares but can have *multiple* sets of preferred shares
* Common shares will always have a *voting weight* of one, while the voting weight of preferred shares is bespoke
* Common shares have no liquidation preference, while preferred shares *can* have a liquidation preference

More details on the following [Share Classes](/protocol/capital-stack/share-classes) section.

## Debt

*The initial version of the Mezzanine protocol has no debt assets and does not yet support liquidation, recapitalization, mergers, or acquisitions. Debt assets can easily be enabled modularly by the Mezzanine team without upgrading contracts. Liquidation, recapitalization, etc. will be added via contract upgrades.*


# Share Classes

{% hint style="info" %}
For technical documentation, please see [MezzShares,](/smart-contracts/source-code/core/mezzshares) [CommonShares](/smart-contracts/source-code/core/mezzshares/commonshares), and [PreferredShares](/smart-contracts/source-code/core/mezzshares/preferredshares)
{% endhint %}

Shares in Mezzanine are similar to those off-chain: they are used in shareholder governance and may be distributed assets in the event of a company's liquidation or acquisition.  There are two types of shares in Mezzanine:&#x20;

1. Common Shares
2. Preferred Shares

There are notable differences between the two:

* There is only a *single* common shares contract in an organization's capital stack.  In contrast, a Mezzanine organization can have multiple classes of Preferred Shares with differing attributes and seniority.&#x20;
* The *voting weight* of common shares is one. The voting weight corresponds to the number of votes that *each* share has in shareholder governance.  Preferred Shares can have bespoke voting weights, allowing them to have more or less voting power than the common shares.&#x20;
* Preferred Shares keep track of a *liquidation preference value*.  This value is the amount of the *denomination asset **per share*** that is distributed to shareholders during liquidation *before* the firm's assets are distributed pro-rata to all equity owners.  Preferred shares do not have to have liquidation preference value.  Once a share class is created, the liquidation preference value is immutable and cannot be increased or decreased.  A shareholder's *liquidation preferenc*e is the product of their balance multiplied by the liquidation preference value.
  * For example, assume that company *Foo*'s denomination asset is USDC.  Foo has 1,000 USDC and no debt.  It also has Preferred Shares with a liquidation preference value of 2, and Alice is the only Preferred shareholder with 100 shares.  Foo also has 100 common shares, where Bob is the sole shareholder.  During liquidation, Alice will receive 2 \* 100 = 200 USDC as her liquidation preference.  The remaining 800 USDC will be distributed between the 200 common and preferred shares, such that Alice and Bob both receive 400 USDC.  In total, Alice receives 600 USDC.

The process of issuing new shares follows two steps:

1. The *authorization* of shares by shareholder governance
2. The *issuance* of those shares by the organization's board of directors&#x20;

The board of directors is unable to issue shares that have not been authorized.  Once issued, the number of authorized shares is decreased.  For example, if company *Foo* has 1,000,000 authorized common shares and issues 100,000, it will have 900,000 authorized common shares remaining. Authorization occurs *per* share class.  If 100,000 common shares are authorized, it does not correspond to the number of preferred shares that are authorized. &#x20;

Common shares will be added to the organization's capital stack upon a company's creation.  The individual(s) who create the company can also dictate an initial number of authorized common shares.

Shares can be issued to any account.  Most frequently, shares will likely be issued to the Treasury, from which they can be spent by the organization's departments and modules.  Like with any ERC20, the spending of shares by a module or department must be *approved* by its ancestors.&#x20;

For the sake of simplicity, the Mezzanine team decided that Mezzanine organizations should only have a single type of common shares.  However, future versions of the protocol can easily support multiple classes of common shares with differing voting weights.


# Debt

{% hint style="info" %}
*The following functionality is **not** available in the first version of Mezzanine.  The foundation for debt assets and debt financing has been properly defined such that these assets can be added modularly to a company's capital stack without requiring any contract upgrades.  Debt financing will not be available by default for Mezzanine companies and must be added retroactively.  The below documentation is subject to change before being implemented in Mezzanine's smart contracts.*
{% endhint %}

## Overview

Debt for Mezzanine companies functions similarly to that of traditional companies.  It is money that must be paid back to the lender, which also (usually) includes an interest rate.

Debt is a powerful tool that provides additional ways to access capital with different implications to the organization's capital structure. &#x20;

Debt in Mezzanine will always be senior to a company's common and preferred shares in the capital stack, limiting its risk profile at the cost of investor upside. &#x20;

Debt will always be denominated in the company's *denomination asset*, which will be a stablecoin.  The purchase of a company's bonds, its coupon payments, and the repayment of its principal will be paid in the company's denomination asset.  A company's denomination asset is determined during its creation and cannot be changed.  All interest and principal payments will come directly from the company's treasury. &#x20;

## Debt Tranches

There may be different tranches of debt that have varying seniority over each other.  In the event of a company's recapitalization or liquidation, debt higher in the capital stack will be paid out before the debt assets that are below them. &#x20;

## Programmatic Liens

The repayment of the principal and interest are *obligatory* payments that constitute a lien on the company's assets, cashflows, and capital structure.&#x20;

It is a serious decision for a company to issue debt. If the principal or interest of a debt asset is not paid according to the agreed payment schedule, the creditor will take ownership of the company via the[ *recapitalization*](/protocol/lifecycle-events) process. Before this occurs, Mezzanine companies have a built-in grace period to catch up on payments and re-enter good standing.&#x20;

Investors, creditors, and founders enjoy completely unambiguous terms and conditions. Programmatic processes enable simulation, since the code dictates the terms rather than the usual paper documents that could be misinterpreted. Paper documents (understandable by lawyers and regulators) can be generated to describe and reflect the terms and conditions written into the smart contracts.&#x20;

## Initial Debt Implementations

Initial implementations of debt will reflect normal debt structures. Debt products will include a coupon rate, maturity date, and frequency of coupon payments. &#x20;

* **Bonds:** Incremental payments of a fixed amount of money, known as *coupons.*  The principal amount will be paid back at the end of the loan.
* **Bullet Bonds:** Principal and interest are all back at the end of the loan period with interest, all at once. &#x20;
* **Amortized Bonds:** Payments are made regularly each period in equal payments.  The principal amount is *not* paid back at the end of the loan.  Instead, payments are made in equal quantities such that the principal is repaid by the bond's maturity. &#x20;

## Debt Offerings

Debt will be sold via *offerings*, which can be completed via a sale or auction.  For example, we will provide an implementations for white listed debt sales, [dutch auctions](https://www.investopedia.com/terms/d/dutchauction.asp), and more. &#x20;

Irrespective of the method used for offerings, a company will need to determine:&#x20;

* The *type* of debt asset being offered
* The maturity date of the debt asset
* A coupon rate&#x20;
* Frequency of coupon payments
* The amount of debt being offered

Assuming that the face value of each bond is standardized, the yield-to-maturity can subsequently be calculated from the provided variables and the investor's bid.

Both investors and companies benefit from debt built with immutable, open-source smart contracts.  Investors can participate in debt offerings that they would otherwise not due to a lack of resources or connections, while companies will acquire a lower cost of capital stemming from greater demand.

###


# Shareholder Governance

{% hint style="info" %}
For technical documentation, see [MezzGovernor](/smart-contracts/source-code/core/mezzgovernor), [StartupGovernor](/smart-contracts/source-code/core/mezzgovernor/startupgovernor), [ShareClassGovernor](/smart-contracts/source-code/core/mezzgovernor/shareclassgovernor), and [LateStageGovernor](/smart-contracts/source-code/core/mezzgovernor/latestagegovernor)
{% endhint %}

## Introduction to Shareholder Governance

Shareholder governance is predicated on *shareholder supremacy*, meaning that shareholders should hold ultimate control of a company. Simultaneously, shareholder governance assumes that most shareholders are relatively naive and uninvolved, so it limits their required participation to a handful of key decisions. Most day-to-day responsibilities are delegated to the board of directors.

Shareholder governance is responsible for a few primary actions:

* Managing an organization's board of directors
* Changing the shareholder governance structure
* Authorizing new shares
* Approving liquidation or acquisition

## Governance Modularity

Shareholder governance in Mezzanine is *modular*.  Mezzanine companies can actively switch between different types of governance to best suit their needs.  For instance, a small startup may desire a governance system that is simple and enables quick execution.  As this company grows and receives more equity financing, it may subsequently switch to a governance system that better empowers decentralized shareholders. &#x20;

Multiple governance modules provides organizational flexibility. One size does not fit all. Future versions of the protocol may provide additional or improved versions of these modules.&#x20;

There are currently three governance modules for companies to choose from, each detailed in the sections below:

1. [Startup Governance](#startup-governance)
2. [Late Stage Governance](#late-stage-governance)
3. [Share Class Governance](#share-class-governance)

{% hint style="info" %}
In Mezzanine, proposals in shareholder governance *are executable transactions.*  If a proposal passes, the transaction(s) can subsequently be executed by anyone.  This type of governance is similar to that of [Compound](https://compound.finance/) and differs from those similar to [Snapshot](https://snapshot.org/#/).  Snapshot uses on-chain events, which are used to index data from a blockchain, to immutably record votes on proposals.  However, the actual execution of a proposal in Snapshot must take place via a trusted party, such as a DAO's multi-signature wallet. &#x20;

In contrast, the execution of a proposal in Mezzanine is trustless: anyone can execute the intended actions of proposals.  While the trustless execution of proposals is a more decentralized governance system, it requires that shareholders be highly cognizant of malicious proposals.&#x20;
{% endhint %}

## Startup Governance

The simplest system of governance in Mezzanine is aptly named *Startup Governance.*  It is most suitable for early-stage startups. This system is extremely simple: the *board of directors*, itself, acts as the governance system. It does not ever require shareholder approval.&#x20;

The board of directors will be able to add new members, remove members, swap members, change their multi-signature wallet's threshold, and authorize shares at their discretion. &#x20;

However, each of these actions requires a *supermajority* of the board to approve, which may be lower or higher than the *threshold*.  A super majority is defined as two-thirds of the board of directors rounded upwards:

***

| Number of Board Members | Super Majority |
| ----------------------- | -------------- |
| 2                       | 2              |
| 3                       | 2              |
| 4                       | 3              |
| 5                       | 4              |
| 6                       | 4              |
| 7                       | 5              |

A supermajority of the board can also approve an upgrade in governance to Late Stage or Share Class Governance.&#x20;

## Late Stage Governance

Late stage governance more closely resembles DAO governance. The shareholders exert an enormous amount of checks and balances over the board of directors. This comes at the cost of speed. It should be used by large, decentralized organizations that do not require rapid actions.&#x20;

Shareholders select/remove board members, approve governance changes, and approve changes to the capital structure, such as dilution, liquidation, or acquisition.

### Voting

There are three different types of votes in late-stage governance:

| Vote Type | Description                                    |
| --------- | ---------------------------------------------- |
| For       | Counts *for* the execution of the proposal     |
| Against   | Counts *against* the execution of the proposal |
| Abstain   | Does not count towards the proposal            |

For a proposal to pass, the number of *for* votes must be greater than the number of *against* votes.  Once a delegate or shareholder casts their vote, their vote is *immutable* and cannot be changed to a different vote type.  Therefore, delegates and shareholders should heavily consider their decision before voting. &#x20;

There are four important elements to late-stage governance in Mezzanine:

1. **Proposal Threshold Percentage:** the minimum number of votes needed by an account to create a proposal.  The number of votes is inclusive of all share classes and vesting shares.
2. **Quorum Percentage:** the minimum number of *for* votes required for a proposal to pass
3. **Voting Period:** The period in which shareholders can vote on a proposal
4. **Voting Delay:** The period in which shareholders can review a proposal and gather votes.  Once the voting delay has passed, any new votes gained by an account cannot be used towards the proposal.  For example, if a voting delay ends at noon and Alice acquires 1,000,000 common shares at 1 p.m., her votes from these shares cannot be used toward the proposal.

The above values can *only* be changed via governance, itself.  However, there are immutable minimum and maximum amounts, such that a malicious proposal to change these variables cannot disable the governance process.  For example, if the proposal threshold percentage was ever greater than 100%, no new proposals could ever be made. &#x20;

<table><thead><tr><th width="258" align="center">Variable</th><th width="147" align="center">Default</th><th width="151" align="center">Minimum</th><th align="center">Maximum</th></tr></thead><tbody><tr><td align="center">Proposal Threshold Percentage</td><td align="center">1%</td><td align="center">1%</td><td align="center">10%</td></tr><tr><td align="center">Quorum Percentage</td><td align="center">10%</td><td align="center">2.5%</td><td align="center">30%</td></tr><tr><td align="center">Voting Period</td><td align="center">3 days</td><td align="center">2 days</td><td align="center">14 days</td></tr><tr><td align="center">Voting Delay</td><td align="center">1 day</td><td align="center">12 hours</td><td align="center">7 days</td></tr></tbody></table>

Some may be curious why the Proposal Threshold and Quorum percentages exist.  The Proposal Threshold percentage is used to prevent spam of proposals by malicious actors.  If it did not exist, anyone would be able to create *any* number of proposals at will.  Similarly, the quorum percentage exists such that an actor cannot execute a proposal with a small number of the total votes.  After all, it does not make sense that a proposal should pass if it would only benefit a small number of stakeholders. &#x20;

These values should be set to best suit the company's needs.  For instance, if it is found that a small shareholder is creating distractive proposals frequently, it may be desired to increase the proposal threshold percentage.  Similarly, the Mezzanine team expects voting activity to differ greatly between organizations.  Organizations with extremely active shareholders should likely increase their quorum percentage, while organizations with inactive shareholders should likely decrease their quorum percentage. &#x20;

The voting delay and period should also likely be adjusted by the size of the organization and the number of shareholders.  Since smaller organizations need to execute quickly, they will probably use shorter voting delays and periods.  Conversely, larger organizations need better checks and balances among stakeholders and should use a longer voting delay and period.&#x20;

### Proposal Cancellation

All proposals in Mezzanine are *cancellable* by the Mezzanine team and a set of individual(s) known as *Defenders*.  The team has designed the cancellation of proposals this way to prevent the exploitation of organizations that receive malicious proposals.  Without doing so, there would be no mechanism to stop an actor from temporarily attaining the majority of votes during the voting delay and executing a malicious transaction.  This behavior greatly increases security at the cost of centralization and may be deprecated in future versions of the protocol. &#x20;

If 75% of a company's *total votes* are voted *for* a proposal, the proposal will become instantly executable: the voting period no longer needs to pass.  This enables smaller organizations, which are more likely to have consensus, to execute proposals rapidly if needed.  Some may be curious why this number is not 50%, since if greater than 50% of a company's total votes are *for* a proposal, it will always eventually pass.  This number was chosen due to its difficulty in acquisition.  In the worst-case scenario, the malicious actor could *instantly* swap the board and subsequently authorize and issue shares to themselves.  However, since a proposal is not instantly executable after attaining \~50% of the total votes, the Mezzanine team will be able to cancel the malicious proposal before its execution. &#x20;

### Voting Delegation

In this governance system, an account's *votes* refer to the voting power that an account has across *all share classes*.  For example, assume that company *Foo* has 2 different share classes: a common shares class with a *voting weight* of 1 and a preferred shares class with a *voting weight* of *5.*  Alice has 1 share of each, meaning that she has 1 + 5 = 6 votes in *Foo's* shareholder governance.  Votes can be *delegated* to another account.  This account can then vote on behalf of the shareholder.  If Alice delegates her votes to Bob, who has no shares, he will have 6 votes to use on Foo's governance proposals, while Alice will have none.  Delegation can be changed at any time, and self-delegation is activated by default.  Delegation takes place across *all* share classes and *all* vesting shares instead of repeated delegation is for *each* share class. &#x20;

### Treatment of Lock-ups & Vesting

*Investors'* shares that are *locked-up* can vote in shareholder governance. However, *employees* cannot vote with shares that have not *vested.* For example, Cynthia participates in company *Foo*'s priced round, receiving 1,000 Preferred Shares with a voting weight of 2 that will be unlocked over 4 years.  She will immediately be attributed 2,000 votes in this governance system.  In contrast, David is an employee who is receiving 1,000 common shares over the next 4 years. He will have no voting power in governance.

### Shares Held by the Company

A company's treasury, its departments, and its modules will *never* have voting power in their *own* governance.  However, a company's treasury, departments, and modules can vote in another organization's governance.  Additionally, any shares owned by the treasury will not be counted towards the total supply of votes.&#x20;

## Share Class Governance

The final governance system in Mezzanine is *Share Class Governance*.  It shares some functionalities of both *Startup Governance* and *Late Stage Governance* and is best suited for mature startups that would like to have major investors participate in governance. &#x20;

Each of the company's share classes are *allocated* board seats.  These board seats can then be subsequently *assigned* by that given share class via a proposal and voting process.  This provides an simple way to share power with large investors of of each investment rounds.

For instance, company *Foo* has two share classes: common shares and preferred shares.  Common share holders participate in selecting the board seats *allocated* to that share class. Preferred share holders participate in selecting the board seat(s) *allocated* to their share class.

Allocated board seats cannot decrease. If a company  increases the number of board seats allocated to their Preferred Shares  to two, it cannot be subsequently decreased to zero or one.  Increasing allocated board seats of a share class requires a supermajority of the board. Common shares have no limit on their allocation of board seats, while Preferred Shares can have up to three allocated board seats. &#x20;

Similar to startup governance, the execution of actions to authorize shares and change the threshold for the board of directors requires a supermajority of signers.  However, the management of board seats requires a proposal process. &#x20;

Unlike Late Stage Governance, proposals in Share Class Governance are *solely* used to manage the assignment of board seats for that given share class.  Assume *Foo* has two board members: Dave and Eve.  *Foo*'s common shares are assigned one board seat, which Dave occupies, and *Foo*'s preferred shares are assigned two board seats, one of which is Eve.  The other seat for *Foo*'s preferred shares remains unassigned.  Shareholders of *Foo*'s Preferred Shares can assign a board member, remove Eve as a board member, or swap Eve with a new board member via the proposal and voting process.  They will have no influence over Dave nor the board seat that he occupies.

<table><thead><tr><th width="279">Action</th><th>Requirements</th></tr></thead><tbody><tr><td>Authorizing shares</td><td>Supermajority of signers</td></tr><tr><td>Increasing allocated board seats</td><td>Supermajority of signers</td></tr><tr><td>Adding a board member for an unassigned board seat</td><td>Proposal and voting </td></tr><tr><td>Removing a board member for an assigned seat</td><td>Proposal and voting </td></tr><tr><td>Swapping a board member for an assigned seat</td><td>Proposal and voting</td></tr><tr><td>Changing the quorum percentage</td><td>Supermajority of signers</td></tr><tr><td>Changing the proposal threshold percentage</td><td>Supermajority of signers</td></tr><tr><td>Changing the voting delay</td><td>Supermajority of signers</td></tr><tr><td>Changing the voting period</td><td>Supermajority of signers</td></tr><tr><td>Switching governance systems</td><td>Supermajority of signers</td></tr></tbody></table>

Quorum and proposal threshold percentages are the same across share classes.  For example, if the quorum percentage is set to 10% and *Foo* has 1,000 common shares and 2,000 preferred shares, a proposal for common shares and preferred shares would require 100 and 200 for-votes to pass, respectively. &#x20;

When switching to this governance system, the board seats allocated and assigned to the common shares will reflect the current state of the board.  For example, if *Foo* has Alice, Bob, and Charlie as board members before switching to this governance system, there will be three allocated board seats who are assigned to Alice, Bob, and Charlie.  There will be no allocated board seats to any of Foo's preferred shares. &#x20;

##


# Modules

Modules in Mezzanine are standalone contracts that contain bespoke functionality.  They are designed to be flexible and interchangeable. Modules usually contain specific logic for various types of spending assets (payroll, recurring payments, vesting, selling/distributing equity) or receiving money (billing, invoicing, subscriptions, streaming, token gating, ecommerce). To start with, a limited number of modules are available from Mezzanine. The long-term objective is to allow any developers to create and integrate many types of modules to provide companies a wide range of choices.

Modules will often be a sole function of a particular department. For example, a company may create a "payroll" department and augment it with a "streaming payroll" module. The payroll department would have authority to use the module and spend up to the amount granted by the treasury (board). Modules may have additional safeguards,  protections, and approvals, depending on their design.&#x20;

{% hint style="info" %}
Technical teams can easily create custom modules in Mezzanine to suit their needs (or as 3rd party software for other Mezzanine companies).  Mezzanine provides a base *Module* contract that can be inherited for hierarchical spending and access control.  For more information about creating a module, see [Creating a Custom Module](/technical-documentation/creating-a-custom-module).
{% endhint %}

Notably, the admin-like functionality of modules should be similar to that of departments.  For example, a subscription module may contain admin-like functionality to determine pricing.  This pricing, in turn, should not only be controlled by its *parent* but all of the module's *ancestors.*

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FFVyocUCGurh3nQqS1cLn%2Fmezz-company-organizational-relationships.png?alt=media&amp;token=9bf3c5aa-7014-4c10-a41e-173c9a8a7817" alt=""><figcaption></figcaption></figure>

In the above examples, both the *Treasury* and the *Finance Department* would be able to determine the pricing in the subscription module.

This hierarchical access control will be available for all Mezzanine-created modules but cannot be enforced for user-created modules due to their bespoke nature. &#x20;


# Equity Financing Module

{% hint style="info" %}
For technical documentation, see [EquityFinancingModule](/smart-contracts/source-code/core/module/equityfinancingmodule)
{% endhint %}

The *Equity Financing* *Module* is special: it is inserted into a company's treasury upon the company's creatio&#x6E;*,* and it cannot be removed.  It is a simple contract that opens new *Priced Round* smart contracts, whose functionality resembles typical Venture Capital funding.  It keeps track of all past priced rounds and the current priced round, if it exists. &#x20;

The Equity Financing module is an *upgradeable* contract.  Future versions will implement more complex financing methods, such as SAFEs.


# Priced Rounds

{% hint style="info" %}
For technical documentation, see [PricedRound](/smart-contracts/source-code/core/pricedround)
{% endhint %}

*Priced Rounds* are smart contracts that resemble Venture Capital Priced Rounds.  They are stand-alone contracts that are meant to be deployed and initialized by the *Equity Financing* module.  They are non-upgradeable contracts. &#x20;

An organization *must* issue shares to the Treasury before the shares can be used in a priced round.  Before shares can be issued, they must be *authorized* via shareholder governance, which will differ based on the organization's governance structure.

A priced round can be instantiated with any share class but will be typically created with Preferred Shares.  Investors should check *where* in the capital stack these preferred shares lie and their respective liquidation preference. &#x20;

A user must also determine eight key variables before opening a Priced Round:

1. The minimum raise
2. The target raise
3. The total shares for the round
4. The price per share
5. The denomination asset
6. An unlock duration, if desired
7. An unlock cliff, if desired
8. An initial unlock percentage, which will be the percentage of shares unlocked following the cliff for investors

{% hint style="info" %}
It is important to remember that the [*shares*](/protocol/capital-stack/share-classes) used in the *Priced Round* contract also include their own properties, such as:

1. Voting weight
2. Liquidation preference
   {% endhint %}

Out of these variables, five are immutable: the *denomination asset,* the *price per share,* the *unlock duration,* the *unlock cliff,* and the *initial unlock percentage.* &#x20;

The denomination asset is the token exchanged for shares, while the price per share is the *number* of the denomination assets that must be exchanged per share.  The denomination asset in the initial version of Mezzanine will be a stablecoin, since most business is denominated in dollars.  Tokens, such as ether or bitcoin, may be whitelisted as a denomination asset in the future. &#x20;

All investors in a priced round will be subject to the same unlock schedule, which is determined by the unlock duration, unlock cliff, and initial unlock percentage.  These variables are immutable.  The *unlock duration* is the amount of time that must pass before an investor can claim *all* of their owed shares.  The *unlock cliff* is the amount of time required to pass before an investor can claim *any partial* amount of their owed shares.  The *initial unlock percentage* is the percentage of shares owed that is claimable once the cliff has passed. &#x20;

Once opened, the organization's board, which are the signers of the treasury multi-signature wallet, can *set* investor allocations.  Two variables make up an investor's allocation:

1. The number of shares
2. The discount or premium to the price per share

From these, an investor's *nominal* allocation in terms of the denomination asset is calculable.  An investor's allocation can be changed at any time.&#x20;

Investors are *only able to invest* their allocated amounts: they are not able to invest lower or higher than their allocation.  For example, if Alice has been allocated 1,000 shares for a priced round, she cannot invest 100 shares.  If an investor wants to change their allocated amount, they must contact the respective organization's board of directors.

Frontrunning checks have been put in place to prevent a malicious organization from exploiting an investor by increasing their premium or number of allocated shares. &#x20;

There are four different *states* that a Priced Round can be in:

* **Open:** The round has been initialized (i.e. opened) and the total raised has not reached the target raise. While the round is still open, investors can choose to revoke their investment, which returns their contribution with no penalty.
* **Closed:** The company closes the round, which transfers the priced round contract's holdings of the denomination asset to the organization's treasury.  Investors can claim their owed shares, and the difference between the total shares for the round and the *allotted shares*, which is the current amount of shares owed to investors who have contributed to the round, is burned.  A round cannot be reopened or canceled once it is closed. &#x20;
* **Filled:** The total raised equals the target raised.  At this point, no further contributions can be made to the round unless investors revoke their commitments or the round is *extended*. The round does not close automatically once filled, this must be completed by the board of directors. While the round is filled, investors can choose to revoke their investment with no penalty. &#x20;
* **Canceled:** The company cancels the round, which burns all shares in the contract and enables investors to recoup their investment.  A round cannot be reopened or closed once it is canceled

When a round is *closed* or *canceled*, its state cannot be changed. However, a round can go from *filled* to *open* if the round is *extended* or an investor revokes their investment.&#x20;

From the above, it is evident that an organization should be generous in setting the number of shares for the round unless they are targeting a certain dilution. If the total number of shares allocated to the contract exceeds the allotted shares, the difference will be burned when the round is closed.  If a round is canceled, all shares will be burned. &#x20;

It is **highly suggested** that the total number of shares allocated for the round *is at least* enough to hit the company's target raise.  Assuming no discounts or premiums in the round, the minimum number of shares to hit the target raise will be *the target raise divided by the price per share*.

Investors have two limitations on whether they can invest despite their allocations:&#x20;

1. If the sum of their *nominal* allocation and the *current* total amount raised exceeds the target raise, they cannot invest
2. If the sum of the *allotted* *shares*, which is the amount of shares owed to investors who have contributed, and the investor's *allocated* shares exceeds the total shares for the round, they cannot invest

Under these circumstances, the investor should reach out to the organization to either extend the round or change their respective allocation. &#x20;

Claiming shares is different *based* on whether or not an unlock schedule has been set.  If no unlock schedule has been set, shares will be *directly* transferred to the investor.  Conversely, the shares will be distributed to the company's *Token Timelock,* which is a smart contract that handles vesting and unlocks of company shares.  The investor then will receive an NFT, through which they can claim their shares according to the unlock schedule.  These NFTs *are* transferable.  All vested shares will go to the *owner* of the NFT, who will initially be the investor.  However, the investor will have the technical capability to sell or transfer their vesting shares, by selling or transferring this NFT, respectively. &#x20;

Mezzanine charges *no fees* for priced rounds.


# SAFEs

SAFEs have ***not** been implemented but will be in future versions of Mezzanine. This provides an additional way of raising money with different properties and mechanics. SAFEs are common fundraising instruments for early-stage startups.*


# Billing

Billing in Mezzanine takes place via a single contract through which all Mezzanine companies interact.  The smart contract used for billing is not redeployed each time that a company is created. &#x20;

Billing in Mezzanine in the initial version of the protocol is simple and does not require the *billable party* to escrow assets, pay a deposit, or pay interest on late payments.  Five variables must be determined to send an invoice to another account:

* The account that is the billable party
* The asset that the invoice is denominated in&#x20;
* The amount to be paid
* The due date
* A category identifier, which will be abstracted from the user

The asset chosen for the invoice must be whitelisted by the Mezzanine team.  Initially, all assets for invoices will be denominated in stablecoins.  The Mezzanine team may choose to whitelist other tokens, such as bitcoin or ether, at a later time.

Once created, each invoice has an identifier.  Paying an invoice requires using this identifier.  Notably, the *payer* (i.e. the party that pays the invoice) does not need to be the billable party.  Rather, the payer merely needs to provide the invoice identifier. &#x20;

The amount specified by the invoice is subsequently transferred directly to the *vendor*, which is the account that created the invoice.  Invoices can be canceled by the vendor at any time. &#x20;

Since invoices do not require any form of escrow by the billable party, there are no on-chain punishments for the refusal to pay an invoice.  The collection of an unpaid invoice for provided services should be enforced via litigation.&#x20;

Category identifiers do not affect the invoice and are used to easily filter paid and unpaid invoices.  An example of a category identifier would be "Advertising".  Quarterly or annual reports could subsequently be automatically created via on-chain event emissions filtered by these category identifiers.


# Payroll

{% hint style="info" %}
For technical documentation, see [PayrollManager](/smart-contracts/source-code/core/payrollmanager)
{% endhint %}

Each Mezzanine company comes natively with a way to compensate employees in both cash and equity.  Employees will pay cash to employees in the company's *denomination asset*, while equity compensation will always be in the company's *common shares*. &#x20;

When offering a candidate a position, six variables must be determined:

* The employee's annual cash salary
* The employee's start date, which must be at least 24 hours into the future
* The employee's equity payments, if applicable
* A vesting duration, if applicable
* A vesting cliff, if applicable
* A vesting initial unlock, if applicable

The candidate can then accept their offer via a cryptographic signature.  If accepted, they will be minted a soulbond, ERC721 NFT upon their hiring.  This NFT contains corresponding information on-chain related to the employee's cash salary, equity payments, start date, etc.  These NFTs and their corresponding on-chain data are preserved even if the company terminates the employee or the employee resigns.  The preservation of this data could subsequently enable future protocol functionality, such as an on-chain credit score. &#x20;

Once the employee's start date has passed, the employee will earn their salary linearly on a second-by-second basis.  For example, if an employee has a $365,000 annual cash salary, they will be able to claim $1,000 every 24 hours, if they desire. &#x20;

*Anyone* can claim the employee's cash compensation on their behalf.  For example, company *Foo* may decide to claim employee Alice's cash compensation on her behalf to better reflect their current cash balance. &#x20;

In the unlikely scenario that a company is unable to pay an employee, any owed cash will be tracked such that the employee can claim it at a future time when the company's treasury has a sufficient cash balance.  This remains true even if the employee is terminated or resigns.

Similar to an employee's cash compensation, an employee's equity compensation can be claimed on a second-by-second basis, can be claimed on behalf of the employee by *anyone*, and begins after an employee's start date. However, an employee's equity payments *must* contain a vesting duration and may contain an initial unlock and a cliff.  Specifically, the employer must decide how many shares the employee will be paid over a specified period. For example, *Foo* may pay Alice 100,000 common shares over four years with a 1-year cliff and an initial unlock of 25,00 shares. &#x20;

The *amount* of common shares used for an employee's equity payments must be available in the company's treasury before their hiring, being given a new vesting schedule, or increasing an employee's equity compensation.  If available, these shares will then subsequently be vested. For example, increasing Alice's equity compensation from 100,000 to 200,000 common shares would require a treasury balance of at least 100,000 common shares. &#x20;

Unlike other parts of the protocol, payroll for a Mezzanine company does not require ERC20 approvals.  An employee will be paid according to their specified salary, so long as there is a sufficient treasury balance. &#x20;

At any point in time, a company can *terminate* or *increase an employee's unpaid time off*.  The latter is akin to *furloughing* an employee in cases where the employee is not requesting a leave.  Both of these actions will collect the employee's cash compensation before taking effect as a means to impede exploitation by the employer.  Notably, an employee's unpaid time off due to a leave or furlough does not have any effect on their equity compensation or vesting.  The termination of an employee will immediately end all future cash compensation and transfer any unvested shares to the company's treasury.  Any severance in cash or equity should be paid directly to the employee before their termination. &#x20;

An employee's resignation functions similar to an employee's termination.  However, an employee can choose an *end date*, which can be up to 90 days in the future.  After the specified end date, the employee will no longer earn any cash or equity compensation.  Any shares that are no longer applicable to the employee's vesting schedule will immediately be transferred to the company's treasury.  For example, if Alice has 100,000 shares vesting over 2 years and resigns such that her end date is 1 year from her start date, 50,000 shares will immediately transferred to her employer's treasury upon her resignation.  A company cannot resign on Alice's behalf. Rather, she must choose to resign, herself. &#x20;

Some actions regarding payroll require a 24-hour time delay before they can be executed.  This time delay is required since a compromised admin could potentially drain a significant amount of company funds instantaneously due to the lack of ERC20 approvals.  A pending action can be canceled by the board of directors, an admin, the Mezzanine team, or a *Defender.* &#x20;

*Defenders are a set of accounts determined by the Mezzanine team, who are solely responsible for increasing the security of the protocol.  They are detailed under the Smart Contract Security section of this documentation*&#x20;

Actions that require a time delay include:

* Changing an employee's cash salary
* Increasing an employee's equity payments and/or their vesting duration
* Setting a new equity payment schedule for an employee
* Paying cash directly to an employee
* Paying common shares directly to an employee

It should be noted that an employee must cryptographically accept any changes to their equity payments.  This is to prevent a company from arbitrarily increasing the employee's vesting duration without sufficiently increasing their equity compensation. &#x20;

Contractors can easily be hired via Mezzanine's payroll functionality.  The process is similar to hiring any employee.  However, the contractor's cash compensation and equity compensation should be set to zero.  Afterward, the employer can pay the contractor directly in cash or common shares as agreed upon.  Again, it should be noted that paying cash or common shares directly to a contractor requires 24 hours to pass. &#x20;

All of the above admin-like functionality, such as hiring an employee, changing an employee's cash salary, terminating an employee, etc. are executable by the company's board of directors and a set of *admins* who are set by the board of directors.  The board can add or remove admins at any point in time.  Admins should be chosen with great care, since, if compromised or malicious, they could potentially steal funds.  However, all routes of exploitation, such as hiring themselves with a bogus salary or paying cash directly to themselves, would require a minimum of 24 hours to pass.  During this period, the board or other admins could terminate the malicious hire or cancel any malicious pending actions. &#x20;

The board of directors may decide to assign admins once the company grows significantly and believes that it is no longer feasible for the board to manage the company's payroll.


# Documents

{% hint style="info" %}
For technical documentation, see [DocumentRegistry](/smart-contracts/source-code/documentregistry)
{% endhint %}

## Overview

Accounts in Mezzanine can store documents via Mezzanine's *document registry*.  The document registry stores *versioned* documents on-chain for *all* Mezzanine departments and boards: it is not redeployed each time that a Mezzanine instance is created. &#x20;

Documents, similar to NFTs, store a *URI* that points to a decentralized storage network, such as Arweave or IPFS.  Files stored on these types of networks are immutable and cannot be changed.  For example, let's look at the [smart contract of *Bored Ape Yacht Club*](https://etherscan.io/token/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d#readContract), a popular NFT collection.  Calling the *tokenURI( )* function with the token id, 0, returns the following URI, which points to IPFS: *ipfs\://QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/0.*

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FuyDkvqi2CsdO1l1lkoTV%2Ftoken_uri_etherscan_bayc.webp?alt=media&amp;token=4d1dd4f3-1d36-42e3-bc25-c89f3efefbf5" alt=""><figcaption><p><em>Query of the tokenURI() function via Etherscan</em></p></figcaption></figure>

If you go to this link, you will find the JSON file that contains the BAYC #0’s metadata:

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FwFz4c8TlSBgtgS5AXAXE%2Fbayc_0_json.webp?alt=media&amp;token=8691de99-9de5-4103-8da1-6d4f995f5f73" alt=""><figcaption><p><em>BAYC 0's Metadata</em></p></figcaption></figure>

These attributes are easily verifiable on [OpenSea](https://opensea.io/assets/ethereum/0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d/0):&#x20;

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FVR2snwNVBzObK2P4Pwv1%2Fbayc_0_OpenSea.webp?alt=media&amp;token=8561f604-7f24-4ad6-b22d-9d447d344975" alt="" width="313"><figcaption><p><em>BAYC 0 on OpenSea</em></p></figcaption></figure>

Files stored on IPFS must have nodes that *pin* them to guarantee that the file is rapidly queryable.  Some of the most common providers for *pinning* are Filecoin and Pinata.  Other decentralized storage networks exist that have similar functionality, such as Arweave.  However, the most widely used decentralized storage network is IPFS. &#x20;

*Read the* [*Pinata documentation*](https://docs.pinata.cloud/docs/what-is-ipfs) *to learn more about IPFS*

The immutable storage of documents in Mezzanine will follow a similar pattern.  In particular, documents store four different variables, one of which is determined by a Mezzanine user:

1. A document name
2. A document URI, which points to a file on a decentralized storage network
3. A version
4. The last time that the document was modified

The document name is the only variable determined by the user with one exception: each organization in Mezzanine will initially have an *incorporation document* that can only be modified by the organization's board of directors.  The initial version of this document will always follow the same syntax.  For company *Foo*, its incorporation document would aptly be named *Foo Incorporation Document*.  Document names and URIs can always be updated by their *owner,* which in turn creates a new version of a document.&#x20;

All documents in Mezzanine are *versioned,* and old versions will always be queryable and immutably stored.  Documents are always versioned at zero, and each time that a document is updated, this version is incremented.  For example, if *Foo* updates its initial incorporation document, the new version of this document will be one.  Any *versioned* document can be updated such that the document's name and URI can be changed at the discretion of the owner. &#x20;

A document URI will be provided and abstracted for all departments, modules, and boards that use Mezzanine.  The Mezzanine team will work with a provider to make these documents easily queryable at all times.  However, the provider and decentralized storage network have yet to be determined. &#x20;

At the time of writing, documents in Mezzanine are *not* access-controlled.  It has yet to be decided whether or not access-controlled documents will be included in the initial version of Mezzanine.  The team is actively considering implementing access control via [*Lit Protocol*](https://developer.litprotocol.com/v2/whatIsLit).  The enforcement of access control would occur *off-chain* via clever cryptography and would not change the above methodology for storing documents. &#x20;

## Uses of Documents in Mezzanine

Certain functionality within Mezzanine is associated with the creation of a new document in the Document Registry.  Here are some examples:

* Assets in an organization's capital stack are associated with a document
* An employment contract is associated with a document&#x20;
* A bill or invoice is associated with a document

The addition of these documents is *optional*.  These actions will simply create a blank document in the document registry with no name or URI if a document is not provided.  For example, if an organization hires someone but decides not to provide an on-chain document, a blank document will be added to the document registry.  This blank document can then be updated retroactively if desired, such that it contains a name and URI. &#x20;

Again, the above actions create *associated* documents.  Specifically, all documents in the document registry are associated with an index.  These indexes are then stored in correspondence with the above actions.  For example, an asset in the capital stack *knows* its corresponding document's index.  This index can then be used to query the Document Registry to clarify the intended functionality of the asset. &#x20;


# Vesting & Unlocks

{% hint style="info" %}
For technical documentation, see [TokenTimelock](/smart-contracts/source-code/core/tokentimelock)
{% endhint %}

All shares in Mezzanine can be vested by anyone, including other smart contracts.  For example, both the Payroll Manager and Priced Rounds support the vesting of shares that are distributed to employees and investors, respectively.  The initial version of Mezzanine will only support *linear* vesting schedules with a *cliff*.

When shares are vested, an NFT is minted to the recipient.  Vested shares can be claimed on behalf of the *owner* of the NFT by *any account*.  For example, if Alice has 1,000 shares vesting over a year, Bob can claim Alice's shares on her behalf (to her wallet) at any time.  The NFTs are *not* soulbound and can be transferred to any account.  Once transferred, the sender gives up all rights to vesting shares. &#x20;

Only a company's shares can be vested in the given company's token timelock.  For example, company *Foo*'s shares cannot be vested in company *Bar's* token timelock. &#x20;

Vesting in Mezzanine can be *obligatory* or *non-obligatory*.  Non-obligatory vesting can be canceled by the board of directors and *admin departments* while obligatory vesting *cannot* be canceled by anyone except the token owner.  Obligatory vesting is used for investor *unlock schedules,* which cannot be forsaken by a company.  In contrast, non-obligatory vesting is akin to a founder's vesting of shares, which should be canceled if the founder is ever terminated or resigns. &#x20;

Admins are whitelisted by the board of directors, such that they can cancel non-obligatory vesting schedules.  Admins can be added or removed at any time.  They do not need to be in the given organization.  However, it is highly suggested that they are.  An admin can be a person, department, or other address.

When vesting is canceled by the board of directors or an admin department, the NFT is burned.  Any unvested shares will be burned if the vesting *is not related to the company's payroll*.  If the vesting is related to the company's payroll, any unvested shares will be transferred to the company's treasury upon cancellation. &#x20;

When vesting, four variables must be determined:

1. The share class
2. The vesting amount
3. The vesting duration
4. The vesting cliff
5. The initial unlock amount

The vesting cliff and initial unlock are *immutable*, meaning they cannot be altered once the vesting NFT is minted.  However, both the vesting amount and duration can be extended by the token owner.

Vesting cliffs act similar to those found in traditional finance.  It is an amount of time that must pass before any shares are vested.  Once passed, the initial unlock amount becomes vested and claimable, and the remaining shares, excluding the unlock amount, are vested linearly.

Vesting for an employee is unable to be canceled by *admins*.  Rather, the employee must resign or be terminated for their vesting to end.  Conversely, any unlock schedules stemming from a priced round are solely cancellable by only the investor, themself.  &#x20;

While Mezzanine's vesting is typically used by other smart contracts, it can also be utilized by individuals who desire to voluntarily vest their shares.  This is typically seen in early-stage startups that are actively raising venture capital funding.  Some venture capital funds require that the founder(s) shares be vested over time to gain confidence in the founder(s)'s commitment.

Vesting does not occur over *periods* but, rather, happens continuously.  This differs from typical vesting, which frequently takes place over quarters.  In Mezzanine, vesting occurs on a second-by-second basis.  An employee or investor can claim their vested shares at whatever frequency they desire. &#x20;

The voting power of vesting shares is maintained and can be delegated to another account.  However, voting with vesting shares by employees is disabled.  For example, if Alice has 1,000 vesting shares as part of her employment contract, she cannot vote with those shares in governance until her shares are vested.


# Lifecycle Events

{% hint style="info" %}
*This section's functionality will **not** be available in the first version of Smart Companies.  A company's capital stack is the foundation for its recapitalization and liquidation and has been properly defined.  Once the implementations have been finalized, existing Mezzanine companies can easily add recapitalization and liquidation functionality via contract upgrades.  The below documentation is subject to change before it is available to Smart Companies.*
{% endhint %}

## Lifecycle Overview

There are a few major events that substantially change the ownership structure of a company, such as incorporation, liquidation, or acquisition. Currently, the terms of these events are scattered between operating agreements, company bylaws, shareholder agreements, side letters, corporate laws, and more. During these events, lawyers and judges from various parties read hundreds of pages of legal documents, then provide the outputs, as if they're processors interpreting code. Of course, lawyers have incentives to interpret the text in front of them differently, depending on who they represent.&#x20;

Smart Companies define critical lifecycle events and provide clear processes to entirely remove ambiguity and dishonest interpretations. The Ethereum Virtual Machine has no biases when it processes code. Currently, companies spend billions of dollars in legal fees clarifying "what happens in circumstance A?" or "what do I get in circumstance B?", when all parties could agree and consent to the same interpretations from the onset, by allowing the code to deliver the proper outcomes.

[***Recapitalization***](/protocol/lifecycle-events/recapitalization) is the process of programmatically transferring ownership from the former equity holders, who failed to uphold obligatory payment, to creditors, who become the new owners. After recapitalization, the company has no debt.  All debt will be converted to preferred equity.&#x20;

[***Liquidation***](/protocol/lifecycle-events/liquidation) is the process of dissolving a company and distributing assets remaining to creditors, investors, and shareholders in a predictable, sequential order. The liquidation waterfall algorithm reflects the organization's [capital structure](/protocol/capital-stack). A Smart Company will only be liquidated if it is approved by the company's governance system.&#x20;

[***Acquisition***](/protocol/lifecycle-events/acquisition) is the process of transferring all assets, debts, contracts, ownership, and control to a new owner, the *Purchaser*, by compensating shareholders of the *Target Company* with cash and/or equity of the purchaser. Normal operations do not cease, there are no changes to the treatment of outstanding contracts, including employment, services, and debt. The only change is the ownership and capital structures.

## Company States

Lifecycle events introduce possible changes to the *company state.* For example, liquidation results in a *defunct* company. Failure to pay debt results in *delinquency* which leads to recapitalization after the *grace period*.&#x20;

<table data-header-hidden><thead><tr><th width="123"></th><th width="167"></th><th width="237"></th><th></th></tr></thead><tbody><tr><td><br></td><td><strong>Solvent</strong></td><td><strong>Delinquent</strong></td><td><strong>Defunct</strong></td></tr><tr><td>Defined as</td><td>Normal operations </td><td>Bad standing for missing payments</td><td>Non-operational</td></tr><tr><td>Enters state by</td><td>Formation, recapitalization, or exiting delinquency through repayment</td><td>Failure to make an obligatory payment, like interest or repayment of principal upon maturity </td><td>Completion of liquidation process</td></tr><tr><td>Exits state by</td><td>Failure to make an obligatory payment or choosing to liquidate</td><td>Paying missed obligatory payments or the completion of recapitalization</td><td>No exiting this state</td></tr></tbody></table>

## Recapitalization & Liquidation Summary

For clarity, we outline the causes and outcomes of recapitalization and liquidation here:

| <p><br></p>       | **Recapitalization**                                                                                                            | **Liquidation**                                                                                  |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Triggered by      | Failure to make obligatory payments                                                                                             | Approval of board and shareholders                                                               |
| Results in        | Shareholders eliminated; creditors become new owners                                                                            | Value distributed in order of the capital stack                                                  |
| Order of Payments | Creditors receive preferred equity in order of the seniority of the debt that they hold; old shareholders are left with nothing | Value is distributed to creditors in order of seniority, then shareholders in order of seniority |
| Outcome           | A new company with preferred shareholders and no debt that may choose to liquidate or resume operations                         | The company distributes value according to capital stack, then becomes defunct                   |
| Initial State     | Delinquent                                                                                                                      | Normal                                                                                           |
| End State         | Normal                                                                                                                          | Defunct                                                                                          |
| New Control       | Creditors                                                                                                                       | None (defunct)                                                                                   |


# Recapitalization

*Recapitalization* is the process of programmatically transferring ownership from the former equity holders, who failed to uphold obligatory payment, to creditors, who become the new owners. One could also call this "programmatic bankruptcy." After recapitalization, the company has no debt.  All debt will be converted to preferred equity. Before recapitalization, a company becomes *delinquent* and has a *grace period* where it has the opportunity to return to make creditors whole.&#x20;

Recapitalization has two phases:

1. Delinquency - a precursor *grace period* of 90 days&#x20;
2. Restructuring of the company such that debtholders become the new owners&#x20;

## Delinquency

Before a company is recapitalized, there a company enters *delinquency*. During this 90-day *grace period*, a company has the opportunity to repay obligations.&#x20;

*Delinquent* refers to a company that misses either the principal or interest payments on its debt.  A company can only exit delinquency through repayment (and return to good-standing) or recapitalization. &#x20;

## Grace Period

During the grace period, the company can catch up on obligatory payments by obtaining cash to fulfill obligations to creditors.  A company may do this in a variety of ways:

* Raise money via new equity financing or debt financing
* Sell illiquid assets&#x20;
* Exchanging liquid assets for the company's *denomination asset*, which can be used to pay back creditors

## Consequences of Continued Delinquency

If the company is unable to become solvent during the grace period, the company is *recapitalized*. The equity holders lose control of the company and the debtholders assume control.  Any remaining amount of the denomination asset is used to pay out the company's most senior debt holders.  Repayment of debt is made *per* seniority level.  All equity owners are wiped out during this restructuring.

Assume that the below is company *Foo*'s capital stack:

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FpscY24b55U4Meu7vaGA9%2Fsimple-mezz-capital-stack.png?alt=media&amp;token=bee136f2-d929-4d8e-9564-ed7d088abda4" alt="" width="220"><figcaption></figcaption></figure>

*Foo* has enough of its denomination asset to make holders of debt asset *F* whole by repaying their principal and interest.  However, *Foo* can only repay debt asset *D's* and a partial amount of *E*.  Under this scenario, *D* and *E* are *not* paid any assets but, rather, are given preferred shares following *Foo*'s restructuring. &#x20;

Creditors will be given ownership that’s directly proportional to the amount of debt that they were owed in the form of preferred shares. Each dollar of debt will convert to one share of preferred equity in the recapitalized company. The *voting weight* and *liquidation preference value* of each preferred share class will be one.  For example, if Alice owned $1,000 of debt, she would subsequently own 1,000 preferred shares with a liquidation preference of $1,000 and have 1,000 votes in governance. &#x20;

The preferred shares will have a seniority structure identical to the seniority structure of the debt. The most senior debt that was unable to be paid in full converts to the most senior preferred equity. This assures that the effect of seniority is preserved if the new shareholders choose to liquidate the company and return capital to shareholders. <br>

<figure><img src="https://lh7-us.googleusercontent.com/u3ej6KzENwfDg8maqQ8iLkAqs_RCOxS1WFZOJ1NdYzFZARUH9-ixNxfjC-r1ODFoEInWBoRIW4Nra-wjWmy2PjyUpJC29m2vTNAU6-xU2yAWVFd7ODmxw0SOmXyyN8pLFK2tzz-ay69O6ycEm7SS7gE" alt=""><figcaption><p><em>Example of a recapitalized company's capital stack</em></p></figcaption></figure>

Once recapitalized, the new shareholders must select a new board.  If not set to *Late Stage Governance*, the governance system is automatically changed to *Late Stage Governance*, giving the shareholders ultimate control over the company.  The company will resume normal operations once the board has been deemed ready. If desired, the new shareholders may immediately liquidate the recapitalized company via governance.  However, shareholders will likely sell any remaining illiquid assets or even the recapitalized company, itself, before liquidating. &#x20;

## After Recapitalization

The new shareholders may choose one of two paths:

1. Raise money and continue operations as the new owners
2. [Liquidate](/protocol/lifecycle-events/liquidation) whatever minimal assets remain

A company may have had illiquid assets or *non-denomination* assets that can be converted to the treasury's denomination and returned to the new shareholders during liquidation.

## Avoiding Delinquency

There are two ways to avoid delinquency.

* A company can never enter delinquency if it never takes on any debt.&#x20;
* A company will never enter delinquency if it stays up to date on all payments. Since the payment of debt and interest is deterministic, the company must manage cash flows and stay up to date on obligations.


# Liquidation

## Liquidation Overview&#x20;

Liquidation is the process of dissolving a company and distributing assets remaining to creditors, investors, and shareholders in a predictable, sequential order. The liquidation waterfall algorithm reflects the organization's [capital structure](/protocol/capital-stack). A Smart Company will only be liquidated if it is approved by the company's [shareholder governance](/protocol/shareholder-governance).&#x20;

If there are no assets in the company's treasury, then liquidation simply closes the company and freezes all operations.  If there *are* assets in the company's treasury when liquidation is approved, then the company begins a process to return money. In either case, a company becomes *defunct* after liquidation.

## Liquidation Process&#x20;

The amount that shareholders and debtholders receive depends on their assets and each asset's place in the capital stack.&#x20;

<figure><img src="https://lh7-us.googleusercontent.com/eQ9ORGDgLIGYMyvAjmJ5Sr4qE1ldaNUkMOaWHfwV1tVdUERjWkqYN_VtxCT-DmzJw9LWgfcrgumVAnlm9gjAP4gKZ2cWlStMVp78bstQzh0Ltvthg0dNsDrJOLGTdVg8cbLmBt2O_ORPxEp22xj5zFc" alt=""><figcaption></figcaption></figure>

The distribution of the company's treasury assets comes in the form of its *denomination asset,* which will be a stablecoin. All of the company's liquid and illiquid assets should be converted to the company's denomination asset before its liquidation.  Any working capital held by departments or modules will be sent back to the treasury.  Upon liquidation, all of the company's employees are terminated, and all unvested employee shares and treasury shares will be burned. &#x20;

Mezzanine companies are likely to have different types of debt and equity, each with a particular place in the [capital stack](/protocol/capital-stack).  Different [classes of shares](/protocol/capital-stack/share-classes) and [debt](/protocol/capital-stack/debt) will express different risk profiles. More senior debt carries the least risk but also comes with the lowest expected returns. Equity carries the greatest risk but comes with the highest return possibilities. Safety is built-in by placing the asset higher on the capital stack than other assets, meaning that assets that are lower on the capital stack would have to be impaired before the most senior debt holders are negatively affected.&#x20;

The company's assets will be redeemed via a *redemption* process.  A redemption contract will be deployed *per debt or share class* with the corresponding number of assets owed.  For instance, company *Foo*'s bond *A* has 1,000 outstanding bonds that are owed $100,000. A redemption contract will be deployed such that bondholders can redeem each bond for $1,000.  Assume that *Foo* has 1,000 preferred shares with a liquidation preference of two, 1,000 common shares, and $10,000 remaining.  The holders of preferred shares should receive their liquidation preference of $2 \* 1,000 = $2,000, and the remaining $8,000 should be distributed pro-rata to shareholders.   A redemption contract for preferred shares is deployed with $6,000, and a redemption contract for common shares is deployed with $4,000.

The redemption of a company's assets has no expiry.  Investors with continuing unlocks can continually redeem their shares for the company's assets.  The Mezzanine team is heavily considering implementing the functionality of the redemption of vesting shares without waiting for the vesting duration.

Below are some examples of liquidation of a solvent company:

<figure><img src="https://lh7-us.googleusercontent.com/W8zVddpYag52CBzr_Y64LPYmFBKzbJZUcpdqQk2Jxh--Dn6Fym0340FBImruib7mu868P_uimhikga7lpXC7dTOjSxY7te4ghfHyICjz1zoOPfe62yai90FW74BFG0hs3e0Fg0eaJ2MsxEf0kUt9AyQ" alt=""><figcaption></figcaption></figure>

## Liquidation After Recapitalization

Companies that have just been recapitalized do not have common shares or debt. It may be common for the remaining debt holders to simply choose to liquidate. The liquidation process may occur with the same order of operations, but it is simply triggered by the new owners (former debt holders):

<figure><img src="https://lh7-us.googleusercontent.com/ovJuPpvYW2dDuFsq7uf8RGWZMWvN18AEzu3_bnQ01QQSPHtwh9dPaIZMOyDfyq6iLCnQG-9yTnB9-fHkYC52B-jAczt3Q6WXb5X-MfWNJoWOQo3AyOc5tbY6teUr2nogJKqodC3gZB9iYdoFrLrzllg" alt=""><figcaption></figcaption></figure>


# Acquisition

*Acquisition* is the process of transferring all assets, debts, contracts, ownership, and control to a new owner, the *Purchaser*, by compensating shareholders of the *Target Company* with cash and/or equity of the purchaser. Normal operations do not cease, there are no changes to the treatment of outstanding contracts, including employment, services, and debt. The only change is the ownership and capital structures.

## Acquisition Proposal&#x20;

The *Purchaser* offers an explicit amount of stablecoins and/or shares to acquire a *Target Company.* If this requires the authorization of additional shares, approval of [shareholder governance](/protocol/shareholder-governance) is required.&#x20;

## Acquisition Approval&#x20;

An acquisition must be approved by the target company’s [shareholder governance](/protocol/shareholder-governance). Before approval, the entire event can be simulated for total clarity to all parties.&#x20;

## Payout Calculations

If the acquisition is approved, the shareholders of the *Acquisition Target*  receive compensation in exchange for the control of the company and all of its assets. Compensation is delivered in the form of cash (stablecoins) and/or shares. The acquisition payout structure follows the seniority structure of shares. This means that investors still receive additional compensation to account for their liquidation preference. If cash is a part of the deal, that first goes to paying liquidation preference. If the deal is all-stock, then investors receive additional stock equal to the dollar-value of the liquidation preference.&#x20;

The process of acquisition include standard treatment for minority shareholders. Minority shareholders enjoy ***tag along rights*** and majority shareholders enjoy ***drag along rights***.&#x20;

## Treatment of Debt

The acquisition process does not directly affect the debt of the company; it is entirely transferred to the new owners along with all existing operating contracts, service contracts, employment contracts, etc. The new owner’s capital stack is now responsible for the assurance of all obligations. After acquisition, if an obligatory payment is not made, delinquency falls upon the acquiring company. <br>


# KYC Procceses

*The implementation for KYC has yet to be finalized.  The KYC process is likely to be done via Mezzanine's embedded wallet and user interface.*

Mezzanine's protocol will be interactable with *any* account that it is deployed on.  Mezzanine KYC processes will be implemented both on the user interface and via the Mezzanine wallet.  The user interface will bar the user from interacting with accounts that are not KYC'd.  Certain actions in Mezzanine's user interface will also require the user to be an accredited investor, such as participating in a company's priced round. &#x20;

The Mezzanine wallet will require on-chain validation via a cryptographic access token to send transactions.  To execute a function via the wallet, a valid signature from a set of validators must be provided.  The exact implementation has still yet to be fully specified. &#x20;

To authenticate, we will utilize privy’s standard OAuth flow.

<br>

The flow is the same for both mezzanine.xyz/app and client’s websites using MezzSDK

<br>

## Authentication & Authorization Flow

To authenticate, we will utilize [Privy](https://docs.privy.io/)’s standard OAuth flow. The flow is the same for both mezzanine.xyz/app and client’s websites using MezzSDK

<figure><img src="https://lh7-us.googleusercontent.com/4km5UkZAYGZAVexMHPzR6RU_0iIn9Lil88JK3mU9iQZ498Dupakm9mr_SmKK_axXKlAtAxFOHGRqZ1olshQ5ZD1RIGzaY6WOBMwUnYiQqC0vOhAXgkwU7C-FAoLUFSCQ6B5wox5z-Hbu2XiM5iOegsQ" alt=""><figcaption><p>Diagram of the auth flow</p></figcaption></figure>

1. **Initiation**: When a user initiates a login via the frontend interface, the backend generates an authentication challenge. This challenge is a uniquely created string formulated in the backend.
2. **Signing Challenge**: The user then employs their embedded wallet (privy) to digitally sign this challenge. The device processes the string and produces a cryptographic signature.
3. **Signature Transmission:** This signature is transmitted back to the frontend.
4. **Verification:** The frontend forwards the signature to the backend. The backend then verifies the signature against the known public key of the user’s embedded wallet.
5. **OAuth Token Generation**: Once verified, the backend issues OAuth tokens to the frontend.
6. **Authorization**: The frontend utilizes the access token to authorize subsequent backend API requests.
7. **Token Refresh**: To maintain continued access, the frontend can request new access tokens using the refresh token, as needed.

## Reauthentication&#x20;

Reauthentication might happen for the following reasons:

* The user signed out and now wants to sign in again
* The user’s access token & refresh token expired due to inactivity, and the user wants to sign in again


# Overview

The following documentation assumes you are familiar with Solidity, its best practices, and the UUPS proxy pattern.  The documentation is meant to summarize complex parts of the code and the protocol's architecture.  For this reason, solidity practices and straightforward functionality will not be thoroughly explained.  For a full understanding of the codebase, it is highly recommended to spend significant time reviewing the code, itself. &#x20;

*Learn more about Solidity* [*here*](https://docs.soliditylang.org/en/v0.8.21/)

*Learn more about common Solidity Patterns* [*here*](https://fravoll.github.io/solidity-patterns/)

*Learn more about Proxy Upgrades* [*here*](https://docs.openzeppelin.com/upgrades-plugins/1.x/proxies)

*Learn more about the UUPS proxies* [*here*](https://eips.ethereum.org/EIPS/eip-1822) *and* [*here*](https://docs.openzeppelin.com/contracts/4.x/api/proxy#transparent-vs-uups)

## Architecture Overview

### Core vs Non-Core

Mezzanine contracts are split between *core* and *non-core* contracts.&#x20;

Core contracts are those related to an *instance* of Mezzanine and deployed as proxies via the *Mezz Deployer.* Core contracts are initialized atomically upon deployment. Examples of core contracts include a company's Treasury, Token Timelock, and Equity Financing Module, among others. &#x20;

Non-core contracts refer to *adjacent* contracts that do not make up an instance of a company.  Non-core contracts are *not* redeployed when a new Mezzanine company is created and include the Billing Router, Document Registry, and Mezz Hub, among others.  Core contracts query non-core contracts for their functionality.  For example, core contracts query the protocol state from the Mezz Hub. &#x20;

### Proxies

*All contracts* in Mezzanine are deployed via EIP-1167 minimal proxies and EIP-1967 upgradeable proxies and follow EIP-1967 storage slots to avoid storage collisions between versions.  Upgradeable contracts follow the UUPS proxy pattern.  The deployment of the Mezzanine companies via proxies drastically reduces the cost of deployments while also enabling upgradeability. &#x20;

Proxies cannot call the constructor of the implementation upon their deployment. Constructors are not stored in a contract's runtime code.  Instead, every contract in Mezzanine that needs constructor-like functionality to initialize state implements an *init* function, which can only be called once. &#x20;

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FI2IUZJ9SxVaLk1PkYRkv%2Fimage.png?alt=media&amp;token=9ee22217-644b-43b5-88b9-0ea6bd76852a" alt=""><figcaption><p>The  Token Timelock's <em>init()</em></p></figcaption></figure>

Some then may be curious as to why Mezzanine contract implementations have a constructor.  Constructors are used to both disable the initializers for implementations and set *immutable* variables.  In Solidity, immutable variables are stored in a contract's runtime code, not storage.  Therefore, the value for the immutable variables across *all* proxies will be the same as the implementation.  This is useful for storing the addresses of the implementation and non-core contracts, such as the Mezz Hub, since these values should not change across company instances. A Mezzanine contract’s constructor will never initialize a storage variable.

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2F7sGqhEbwJarNGBtiR7Yo%2Fimage.png?alt=media&amp;token=be95d7e2-78fb-446b-b2a5-4aef71f2b145" alt=""><figcaption><p>The Hub Aware contract's constructor and immutable variables</p></figcaption></figure>

### Mezz Hub

All core implementations, excluding Mezz guards, are aware of the MezzHub.  Core contracts query the following information from the Mezz Hub:&#x20;

1. The address of the *Fee Controller*
2. The address of the *Document Registry*
3. The address of the *Mezz Deployer*
4. The protocol state
5. Whether or not an address is a whitelisted denomination asset
6. Whether or not an implementation is frozen
7. Whether or not a deployment is frozen
8. Whether or not an address is a *defender*

The Mezz Hub sits at the heart of the Mezzanine protocol.  All core and non-core contracts rely on the Mezz Hub's state for their functionality.  It is by far the most centralized contract across the entire protocol.

The Mezz Hub is *ownable*.  Ownable contracts are frequently used throughout Solidity codebases.  The terminology stems from OpenZeppelin's [*ownable* implementation](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/01ef448981be9d20ca85f2faf6ebdf591ce409f3/contracts/access/Ownable.sol).  Ownable contracts are controlled by an admin, referred to as the *owner*.  Access control is implemented such that only the *owner* can call admin-like functions. &#x20;

The *owner* of the Mezz Hub will be a multi-signature wallet controlled by the Mezzanine team and will have special privileges.  The *owner* of the Mezz Hub can:

* Call admin-like functions for non-core contracts, setting their state
* Reset or set new core implementations in the *Mezz Migrator,* which is responsible for versioning implementations and upgrading contracts
* Cancel any pending proposals or pending actions in shareholder governance or a company's payroll
* Set the protocol state
* Freeze deployments or implementations&#x20;
* Whitelist denomination assets
* Reset any upgradeable core contract to a patched version, given that the protocol state is not *Active*

Each signer of the multi-signature wallet that is the *owner* of the Mezz Hub will safeguard their keys using best security practices.  An adequate number of signers will be used to decrease security risks stemming from centralization. &#x20;

### Protocol State

The Mezzanine protocol's state is set in the Mezz Hub.  The protocol can be in three different states:

|                             | Active   | Paused            | Frozen                 |
| --------------------------- | -------- | ----------------- | ---------------------- |
| Core contract Functionality | Enabled  | Partially enabled | Vast majority disabled |
| Upgrades to new versions    | Enabled  | Disabled          | Disabled               |
| Patches                     | Disabled | Enabled           | Enabled                |

## Contract Upgrades

Contract upgrades in Mezzanine follow strict rules such that a contract can only change its implementation following strict version control.  The Mezzanine team has chosen to enable migrations via upgrades to enable companies to update the logic of their contracts without altering or copying contract storage. Without upgrades, migrating stored data would be extremely costly at scale.  Consider a company with 100 employees.  To upgrade to a new method of payroll, 100 new employee contracts would need to be made for the sole purpose of updating contract logic. &#x20;


# Smart Contract Security

The Mezzanine team has created smart contracts with the philosophy that writing bug-free code is impossible. Instead, Mezzanine's smart contracts were designed to be patchable given a route for exploitation is discovered. &#x20;

The vast majority of the smart contracts that make up a Mezzanine company are deployed with *upgradeable* proxies.  These proxies must follow strict logic for their implementations to be changed and cannot upgrade to an implementation that was not chosen by the Mezzanine team.  This upgradeability enables Mezzanine to patch any vulnerable smart contracts, impeding the exploitation of companies. &#x20;

All of Mezzanine's smart contracts will be sufficiently audited before being put into production and a proactive security monitoring system will be put into place. &#x20;

### Protocol State

All of Mezzanine's smart contracts are also aware of the *protocol state*, which can be three different settings: *Active, Paused,* and *Frozen.*

All of Mezzanine's functionality will be enabled if the protocol is *active*.  Conversely, if the protocol is *frozen*, the vast majority of Mezzanine's functionality will be disabled, thereby preventing companies from being exploited.

*Paused* is an in-between between *Active* and *Frozen* states, disabling some functionality while keeping some enabled.  As a rule of thumb, functionality that lets users *enter the protocol* will be disabled when the protocol is paused while functionality that lets users *exit the protocol* will be enabled.  For example, *hiring* an employee will be disabled if the protocol is frozen while *terminating* an employee would be enabled. This state is desired if there is specifically a bug found with code that enables users to enter the protocol but not with code that lets users exit the protocol. &#x20;

Contracts can be upgraded to patched versions that fix any route for exploitation in the paused or frozen protocol states. &#x20;

### Freezing Implementations and Deployments

The Mezzanine team can freeze specific implementations, which would subsequently be patched.  For example, if a bug is found in Mezzanine's payroll manager, the specific implementation can be frozen such that all of Mezzanine's other functionality is maintained.  The team would then unfreeze this implementation once each company's implementations have been patched. &#x20;

The Mezzanine team can also freeze specific company deployments.  For example, the team can freeze the payroll of company *Foo* while keeping the payroll of company *Bar* enabled.  This functionality may be desired if it is found that the signers of a specific company are compromised or the company is found to be malicious.

### Canceling Proposals and Pending Actions

Certain actions for Mezzanine companies require a time delay, such as a governance proposal or a pending action in payroll.  These actions can be canceled by certain parties, such as the proposer of the governance proposal.  In addition, the Mezzanine team can cancel any proposals it views as potentially malicious.  Once canceled, contact will be made with the team.  The proposal or pending action can then be re-proposed if found non-malicious. &#x20;

### Defenders

A set of accounts known as *Defenders* will be responsible for maintaining protocol security in addition to the Mezzanine team.  Defenders can:

* Freeze the protocol for up to 14 days
* Freeze deployments, which in turn would freeze the functionality of a specified Mezzanine company
* Cancel proposals and pending actions of any Mezzanine company

Defenders will be well-known parties with extensive security knowledge, such as smart contract auditing firms. &#x20;


# Deployment of Core Contracts

The Mezz Deployer is the smart contract responsible for deploying proxies of *core* contracts.  It is a *non-core* contract.  The Mezz Deployer specifically deploys new [minimal, non-upgradeable EIP-1167 proxies](https://eips.ethereum.org/EIPS/eip-1167) and [ERC1967 Proxies ](https://eips.ethereum.org/EIPS/eip-1967)that point to implementations of Mezzanine core contracts.  Proxies are used to reduce deployment costs since their runtime code is much smaller than that of implementations.  The cost of a contract's deployment is directly proportional to the size of its creation and runtime code.

Implementations are versioned and set in the *Mezz Migrator*.  Proxies deployed by the Mezz Deployer will always point to the latest implementations set in the Mezz Migrator.  Implementations are queried from the Mezz Migrator when provided *core identifiers*, which point to the latest version of an implementation.

Upon deployment, all proxies are initialized atomically.  Multiple major exploits have occurred from improper initialization.  Some core contracts deploy contracts from the Mezz Deployer and subsequently set state atomically.

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FxSgIhyoPnBMFm2mFW3fC%2Fimage.png?alt=media&amp;token=9746ee2c-8fcd-41bf-8631-7f1af9b6f49b" alt=""><figcaption><p>Code Snippet from <em>TreasuryLogic.sol</em></p></figcaption></figure>

The initialization of deployments is *standardized* as a means to reduce the size of the Mezz Deployer.  Bespoke initialization arguments are passed via abi-encoded parameters.  For example, all assets in Mezzanine are deployed via the Mezzanine Deployer's *deployAsset* function.  Assets are all initialized in the same manner.  The validity of implementations is checked via ERC165.  In the below code, the function would revert if given a core identifier that does not correspond to an asset. &#x20;

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2F4sZwyeBc5BRd4wlDSEFS%2Fimage.png?alt=media&amp;token=8716bfd0-f8c9-4ac3-87a1-4ec38390c942" alt=""><figcaption><p>Mezz Deployer's <em>deployAsset</em> function</p></figcaption></figure>

*Learn more about Creation vs Runtime code* [*here*](https://blog.openzeppelin.com/deconstructing-a-solidity-contract-part-ii-creation-vs-runtime-6b9d60ecb44c)*.*

*Learn more about the gas cost for the CREATE opcode* [*here*](https://github.com/wolflo/evm-opcodes/blob/main/gas.md#a9-create-operations)*.*


# Contract Upgrades

*Migratability* refers to the process by which a *core* contract can be upgraded to a different version with more functionality.  Migrations are completed via the *MezzMigrator*. &#x20;

## Mezz Migrator

The *Mezz Migrator* is the contract responsible for upgrading core contracts to new or patched versions.  For an implementation to be set in the Mezz Migrator, it must inherit from the *Credentialed* base contract, which requires inheritors to implement a *core identifier and version*, which should return a bytes32 and uint256, respectively.  Upgradeable core contracts also inherit from *MezzUUPSUpgradeable*, which overrides [UUPSUpgradeable's](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) *\_authorizeUpgrade* internal function such that only the Mezz Migrator can call *upgradeToAndCall*, which atomically upgrades a proxy's implementation and executes an initialization function via a delegate call.  Contracts that inherit from UUPSUpgradeable are deployed via [ERC1967 proxies.](https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Proxy) &#x20;

### Core Identifiers and Versioning

Each core identifier in Mezzanine is associated with a set of implementations in the Mezz Migrator, which are versioned from one.  For example, the *Treasury* will have a version of *1* when the Mezzanine protocol is first deployed.

Versions in Mezzanine follow the X.Y format, similar to that found in the [Semantic Versioning standards](https://semver.org/).  X is incremented when the version is not backward compatible with prior versions.  Y is incremented when a new implementation is set in the Mezz Migrator.  Therefore, the *version* *function* in MezzUUPSUpgradeable contracts refers to *Y*, while X is defined in the calculation of the core identifier. &#x20;

Core identifiers are calculated for each contract as follows:

```solidity
bytes32 internal constant CORE_ID = keccak256(abi.encodePacked("mezzanine.coreId.CONTRACT_NAME.vX"))
```

where *CONTRACT\_NAME* is the name of the contract and *X* corresponds to *X.Y i*n the semantic versioning standards.

The return value of a contract's version will be off by a factor of one from the semantic versioning standards since versions are indexed at one.  For example, a treasury implementation of version 2 and a core identifier of the hash of "mezzanine.coreId.Treasury.v1" would correspond to V1.1. &#x20;

The Mezz Migrator is responsible for versioning contracts even when they are not upgradeable.  For example, the Common Shares and Preferred Shares contracts are non-upgradeable.  They are deployed via the Mezz Deployer.  The latest versions for these contracts will always be queried from the Mezz Migrator and subsequently deployed.  Older versions will never be used. &#x20;

The latest version of an implementation can be patched if the core contract is upgradeable.  Specifically, the latest version of a core identifier would be updated to a new implementation.  The protocol or the exploitable implementation can then be *paused* or *frozen* to reset to the contract to the patched implementation. &#x20;

### Upgrading Core Contracts

*MezzUUPSUpgradeable* contracts store the address of the *MezzMigrator* as an immutable variable that is set in their constructor.  Behavior from *UUPSUpgradable* has been overridden such that the MezzMigrator, itself, must be the caller to upgrade a contract.  A core contract can upgrade itself by calling the MezzMigrator's *upgradeToNewerVersion* and *resetToPatchedLatestVersion* functions.  Calling these functions will perform a callback on the caller's *upgradeToAndCall* function.  Arbitrary calldata can be provided if needed to call a *re-init* function, which acts similarly to a constructor for the new version.  The methods by which core contracts call these functions are bespoke.

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2Fw9SxGOxwfuZQBv4MWEu9%2Fimage.png?alt=media&amp;token=7ce0e9aa-7bb1-48af-bd17-ef3b406669b3" alt=""><figcaption><p><em>upgradeToNewerVersion</em> from the Mezz Migrator</p></figcaption></figure>

\
In the event of a route for an exploit, backdoors to key core contracts have been implemented such that they can be upgraded to newer versions by the owner of the Mezz Hub, even if a company has not requested an upgrade.  This behavior can be decremented in future versions.  However, it was implemented this way as a means to allow the Mezz Team to quickly patch potential routes for exploits for inactive companies. &#x20;

### Steps for Patching an Exploitable Version of a Core Contract

The Mezzanine may push a version with a potential route for an exploit.  To patch exploitable contracts, the Mezzanine team should take the following steps:

1. Freeze the protocol&#x20;
2. If undiscovered, identify where and how the exploit is taking place.  Otherwise, skip to step 3
3. Freeze the relevant implementations and/or pause the protocol
4. Reset the latest version’s implementation to a patched version&#x20;
5. Notify users to upgrade their core implementation contracts to the patched version or have the Mezz team patch on behalf of users
6. Once all core implementations have been patched, change the protocol state back to active

Minor bugs can be patched following a much more lenient process:

1. Set a new version of the core contract with the patched implementation
2. Request that users upgrade to this newest version

## Risk Management

Core contracts can only be upgraded via the *Mezz Migrator* when a callback is performed on the core contract's *upgradeToAndCall* function.  *upgradeToAndCall* makes an internal call to *\_authorizeUpgrade*, which can be overridden to add access control.  *MezzUUPSUpgradeable* contracts override this function such that the Mezz Migrator must be the caller when upgrading contracts.

*upgradeToAndCall* atomically upgrades a proxy's implementation and executes an arbitrary delegate call onto the upgrading contract's implementation.  Calldata is validated such that it cannot be another call to *upgradeToAndCall,* forgoing Mezzanine's strict version control.  This arbitrary call is meant to be towards a contract's *init* or *re-init* function in case the new implementation needs to initialize or set state to function properly.  Doing so improperly may lead to a potential route for exploitation in the upgraded contract.  The provision and validation of calldata provided during an upgrade should be provided on Mezzanine's interface, and incorrect or the lack of calldata should be flagged. Mezzanine's smart contract developers should also design any re-initialization functions to minimize any route for exploitation. &#x20;


# Mezz Guards

## Overview

Guards are an important component of s*afes*, which are multi-signature wallets designed by Safe (formerly Gnosis Safe).  A safe can set another contract to arbitrarily block certain transactions. Departments and treasuries in Mezzanine directly inherit from safe, enabling them to have multi-signature functionality.  As multi-signature wallets, they can execute arbitrary transactions so long as a sufficient number of signatures are provided.  Guards in Mezzanine are key in blocking both departments and treasuries from managing their signers, resetting their guard, changing their threshold, or executing an arbitrary delegate call.  Guards are atomically deployed with departments and treasuries by the Mezz Deployer. &#x20;

## Safe's standard functionality

A standard safe manages its signers (known as *owners* in Safe's source code) and guard by executing an external call on *itself* via its multi-signature functionality.  This guarantees that the *threshold* is reached when changing its state. &#x20;

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FDHa5IM0ksZKZyuEJTNz3%2Fimage.png?alt=media&amp;token=2aef97a2-f37c-4e6a-9899-e1892d8c57b0" alt=""><figcaption><p>Safe's <a href="https://github.com/safe-global/safe-smart-account/blob/f03dfae65fd1d085224b00a10755c509a4eaacfe/contracts/common/SelfAuthorized.sol"><em>SelfAuthorized</em></a> <em>base contract</em></p></figcaption></figure>

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2F4daecvvWiyJ04vLwGArP%2Fimage.png?alt=media&amp;token=56ccc857-a3dc-44ba-9aac-442e0b26c2ea" alt=""><figcaption><p><a href="https://github.com/safe-global/safe-smart-account/blob/f03dfae65fd1d085224b00a10755c509a4eaacfe/contracts/base/GuardManager.sol#L79-L100">Code Snippet from Safe's <em>OwnerManager</em></a>, which safes inherit.  Notice that the <em>authorized</em> modifier is used here.</p></figcaption></figure>

A guard's *checkTransaction* function is called each time that a safe uses its mult-signature functionality:

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FNMXoONmM01cqtvTBITLz%2Fimage.png?alt=media&amp;token=3026467f-4c61-4983-ad7b-61628054b86d" alt=""><figcaption><p><a href="https://github.com/safe-global/safe-smart-account/blob/f03dfae65fd1d085224b00a10755c509a4eaacfe/contracts/Safe.sol#L171-L191">Code snippet from a safe's <em>execTransaction</em>,</a> which is responsible for executing multi-signature, arbitrary transactions</p></figcaption></figure>

The blocking of calls by a guard is completely bespoke and up to the implementation.  It should be noted that *checkTransaction* is called via a *static call* and does not change state.

## Mezz Guards

Guards in Mezzanine, known as *Mezz Guards*, are used to block direct calls made to manage a treasury or department's signers, its threshold, or its guard:

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FnEHw7HlkhBQySJgrl6Kj%2Fimage.png?alt=media&amp;token=a2309122-5bb9-477a-8222-517effca605f" alt=""><figcaption><p>Code snippet from the MezzGuard base contract.  <em>SafeTxValidation</em> is a library to validate that 'data' does not correspond to managing a safe's signers, setting a guard, or enabling a safe module</p></figcaption></figure>

These functions can only be called via other functions, which enable strict access control.  For example, only an ancestor can swap the guard for a department:

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FREBUjNwWGy89V04QkvFw%2Fimage.png?alt=media&amp;token=7136554a-c792-4173-b625-aa33685c0e5f" alt=""><figcaption><p>A department's <em>swapGuard</em> function. The <em>onlyAncestor</em> modifier will cause this function to revert if not called by an ancestor</p></figcaption></figure>

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FGPPiNj2LvlOK9UGYNEB2%2Fimage.png?alt=media&amp;token=bea29e71-3948-4809-be58-47e60d04037d" alt=""><figcaption><p>TeamLogic's <em>swapGuard</em> function, which is called above. Deploys a MezzGuard via the MezzDeployer and calls on the contract itself, passing the Safe's <em>authorized</em> check</p></figcaption></figure>

A Mezzanine treasury or department *cannot* change their guards to user-created ones.  Guards must be deployed via the Mezz Deployer, which deploys implementations that the Mezzanine team sets.

There are three different types of Guards in Mezzanine: a *whitelist guard*, a *blacklist guard,* and a *shareholder guard*.  Treasuries and departments can use any of these three guards.  By default, all departments and treasuries use a *blacklist*, since it is much less heavy-handed.  Whitelists should only be used when the restriction of a department's capabilities is of the utmost importance. &#x20;

A Mezz Guard keeps also track of *two* *lists* which can be used as either a whitelist or blacklist depending on the implementation.  One list is an enumerable set of contract addresses, while the other ‘list’ is a dynamic array of g*uard selectors*.  A guard selector is the pairing of a contract address and a function selector.  <br>

<figure><img src="https://lh7-us.googleusercontent.com/TWN5aCL7ThWOtzHFDBQyLodYajIifMSBUOX30ydwJC8mkCzrr7MYgmhVWIA98_IHzQSzmVzeMfJvU7oE4QcCmel9l1JgNN3mQLU4M2kswfQKvFX5rQHhD-TZ-qUayR_ZpKS7oL_ZdGbsre-XLgCqieA" alt=""><figcaption><p>Code Snippet from Mezzanin'es DataTypes.sol</p></figcaption></figure>

For example, assume a department uses a guard that is a blacklist.  The guard's *contract list* contains the billing router, and its list of guard selectors contains USDC and the function selector to *transfer.*  All calls to the billing router or to transfer USDC by the department will *revert* if called via its multi-signature functionality. &#x20;

Both whitelist and blacklist guards will check in their *checkTransaction* function if the call is made to any contracts or guard selectors *on the list*.&#x20;

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2FLTQ27CUiFRCoF2M4ph7y%2Fimage.png?alt=media&amp;token=97637403-5d8b-4c72-9f7e-5bd30d4ea182" alt=""><figcaption><p>Blacklist Guard's <em>checkTransaction function</em></p></figcaption></figure>

<figure><img src="https://1470005141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FdHjZFJeNjVY4yO2OTNVA%2Fuploads%2Fn5NLKWbQTo14mQS0Rurc%2Fimage.png?alt=media&amp;token=b97c0ae8-fbf3-4c4c-ac40-17f718daa977" alt=""><figcaption><p>Mezz Guard's <em>onList</em> function, which Blacklist Guard inherits</p></figcaption></figure>

&#x20;If either of these conditions is true, the blacklist guard will revert the transaction, while the whitelist guard will *not* revert the transaction.  This enables a department’s ancestor or the treasury’s governance to either blacklist or whitelist certain function calls. &#x20;

By default, Mezzanine uses blacklist guards.  Whitelist guards require an extensive amount of overhead.  Due to the high number of dependencies in Mezzanine, all other core contracts, such as the token timelock,  would need to be whitelisted in addition to all other non-Mezzanine contracts that the department may use. &#x20;

Guards can be easily changed from one implementation to another.  It should be noted that when a guard is swapped, the lists are not maintained.  For example, if a whitelist guard is used such that swaps on a DEX revert, those transactions will not be blocked if the user swaps to a blacklist guard.  Instead, the *controller* of the guard must manually update the list.

Each guard has a *controller* which is set during the guard's initialization.  The controller is responsible for setting the contract and guard selector lists.  The controller of a department's guard will be its parent, while the controller of a treasury's guard will be the system used for shareholder governance. &#x20;

The *shareholder guard* is unique.  It is a blacklist guard whose *controller* is always the company's governance system.  Departments may want to use a shareholder guard in special circumstances.  For instance, a Mezzanine company may desire to be more democratic in its operations.  All decisions then to blacklist transactions for departments should then stem from governance.  Treasuries, by default, are deployed with shareholder guards.  <br>


# Documents

The *document registry* is a non-core contract used throughout the protocol.  It is not redeployed each time that a Mezz organization is created.  Rather, all instances of Mezzanine use the same document registry.  Notably, the document registry in Mezzanine is not access-controlled.  Anyone can add documents to the registry if desired. &#x20;

A document is made up of four different variables:

<figure><img src="https://lh7-us.googleusercontent.com/Hy36H-Dn22ROSHdp-TuODS9MfyHIEO8IayKNrJVsaYs9ZaQic7Ilfkww-YCQQBQp7lsImkwfG-WHjrajOImyEtSDZn-yzwrPpqiZumSykqXbMEh9E34vSjQagvHTy5TAqWheVf477gDe4cXRvMD6tr8" alt="" width="375"><figcaption><p>Code snippet from Mezzanine's DataTypes.sol</p></figcaption></figure>

Documents are always versioned, and previous versions are always stored on-chain:

<figure><img src="https://lh7-us.googleusercontent.com/07rva_0z5mnuXaba1Fosp84oGEoTrHo4IkBD-yXLZL5HLg09ycc41yLEfuwAOhHcPPyG8QAK828Dqnm-r8hAvXm9rDFVVDNY0WZepoQsZxHgG0Jv62G85Y3Yb4oS12g8NSZiNLYefrMC0sjbwp5M1X8" alt=""><figcaption><p>Code snippet from Mezzanine's DataTypes.sol</p></figcaption></figure>

Whenever a document is updated, *nextVersion’s* current value is set to the updated document, and it is subsequently incremented.  Only a document that exists can be updated. &#x20;

Versioned documents are always associated with an *owner*, and each document is associated with an index.

<figure><img src="https://lh7-us.googleusercontent.com/YFoMjBGYhxBVu0Jm1A8vXskoPDOPbXY3vXde10STtJMKi8vTu-z2OWhA6W6Uh4I9vG5Jmzw41Bro2UqVJH4Bz_QVJwru-ELTidksWKBogzWP0E8i3DPl_bkClHEgs8PUvYuxuaeWEzOp7IMrfkxAQeA" alt=""><figcaption><p>Code Snippet from DocumentRegistry.sol</p></figcaption></figure>

The exact methods for access control for documents have yet to be determined.  Access control for documents would occur off-chain, such as by using [Lit Protocol.](https://www.litprotocol.com/)  The URIs, themselves, will likely be stored on IPFS with the providers either being Filecoin or Pinata.  However, this has yet to be determined.  Initial versions of Mezzanine may have document URIs that point to a centralized interface. &#x20;

Generally, a document's name and URI are set by the users, themselves.  There is a single exception: a company will always be created with an incorporation document and its initial name will be “*Company Name Incorporation Document*”.  The owner of the Incorporation Document is the Treasury contract.  The name and URI can always be updated by the Treasury later on if desired. &#x20;

At various points throughout the codebase, certain mappings keep track of a document index.  For example, an asset in a company's capital stack will always point to a document.  However, this document is not guaranteed to have an accurate, valid name and URI. &#x20;

Certain actions in Mezzanine will always create a document:

* Adding an asset to the *capital stack*
* Sending an invoice via the *billing router*&#x20;
* Hiring an employee via the *payroll manager*
* Creating a Mezzanine company

Old versions of a document are always queryable and immutable.  The URI of an old version cannot be changed on-chain.  However, depending on the system used for URIs, a URI may point to a new document if Mezzanine does not use a decentralized storage system.

Departments and Treasuries are multi-signature wallets.  Therefore, they can execute arbitrary transactions on their own.  However, modules and ancillary contracts are standalone contracts and are unable to execute arbitrary transactions.  Each of them contains logic to update their documents.  "Removing" documents is akin to setting the document’s name and URI to null values. &#x20;

The Document Registry is upgradeable and can only be upgraded by the owner of the Mezz Hub, which will be the Mezzanine’s multi-signature wallet. &#x20;

Notably, the document registry's functionality is not aware of protocol state, since its functionality never deals with user funds.  Therefore, it realistically never needs to be paused or frozen. &#x20;


# Glossary

{% hint style="info" %}
Some of the below terminology relates to a company's debt, recapitalization, and liquidation. This functionality has not yet been implemented for Mezzanine companies but will be included in future versions
{% endhint %}

* **Ancestor:** a node reachable by repeated child-to-parent relationships. Differs from the traditional definition in that a node is not considered an ancestor of itself.  Access control should be maintained such that an ancestor can execute the admin-like functionality of its descendants.
* **Asset Class:** a group of assets that share similar characteristics.  An *asset* in Mezzanine, such as common shares, and *seniority levels* is aware of their asset class.  There are three asset classes in Mezzanine: *common equity*, *preferred equity*, and *debt*. &#x20;
* **Billing Router:** a *non-core* contract that each Mezzanine company can use to send invoices to one another.  An invoice is defined by its *denomination asset*, the amount to be paid, and its due date.  Companies do not have to use Mezzanine's billing router and can implement their own versions
* **Capital Stack:** defines the various forms of capital that are used to fund the operations and growth of a Mezzanine company. A capital stack is made up of *assets* and *seniority levels.*  The ordering of seniority levels defines which assets in the capital stack will be distributed other assets during a company's liquidation, recapitalization, or acquisition.  Deployed with each Mezzanine company. &#x20;
* **Core Identifier**: a unique hash that corresponds to the implementation of a *core* contract
* **Child:** each node can have a set of nodes immediately below them, known as children.
* **Core Contract:** a contract that acts as part of a Mezzanine company.  Core contracts are redeployed via proxies by the Mezz Deployer.  Some core contracts are upgradeable while others are not
* **Defenders**: a set of accounts responsible for maintaining the protocol's security.  Can cancel potentially malicious governance proposals or pending payroll actions, *freeze* the protocol for up to 14 days, or freeze a company.  The Mezzanine team is responsible for managing *defenders*. &#x20;
* **Denomination Asset:** a set of whitelisted stablecoins that are used to *denominate* a company.  A Mezzanine company defines its denomination asset upon its creation.  A company's debt, payroll, liquidation, and recapitalization will always use this asset. &#x20;
* **Department:** a Safe (formerly Gnosis Safe) multi-signature wallet that can spend funds recursively from a company's treasury, given sufficient approvals.  Can insert modules and other departments as *children.*  The responsibilities of a department are bespoke.  Can mange the signers of its *descendant* departments and execute admin-like functions of *descendant* modules. &#x20;
* **Descendant:** A node reachable by repeated parent-to-child relationships
* **Equity Financing Module:** responsible for a company's equity financing and deployed with each Mezzanine company.  Creates *priced rounds* and tracks the order in which they occur.  Users can freely create new equity financing modules. &#x20;
* **Fee Controller:** a non-core contract used to set on-chain fees in the Mezzanine protocol.  The maximum fee is 3%.  The Mezzanine team currently has no plans to monetize the protocol on-chain but may choose to do so in the future.
* **Governor:** a smart contract that defines the governance of the company.  Responsible for the authorization of shares, the management of the board of directors, the changing of governance systems, and the voluntary liquidation of a company.
  * **Startup Governor:** a governance system in which the *board of directors*, themselves, act as governance.  Each governance decision requires a *supermajority* of the board to agree&#x20;
  * **Share Class Governor:** a governance system in which each of a company's *share classes* is allocated a number of board seats.  The allocation of these board seats follows a proposal and voting process separated by share classes.  The changing of a treasury's *threshold,* a change to a new governance system, and the authorization of new shares require a supermajority of signers
  * **Late Stage Governor:** a governance system in which all governance actions require a proposal and voting process. &#x20;
* **Mezz Deployer:** deploys new proxies to implementations of core contracts
* **Mezz Guard: a** safe guard that is used to block certain calls.  Safe guards are smart contracts used to validate the data of a multi-signature wallet transaction.
* **Mezz Hub:** a non-core contract responsible for setting protocol state, managing *defenders*, and whitelisting denomination assets, among other responsibilities.
* **Mezz Migrator:** a non-core contract responsible for versioning implementations, *migrating* core contracts from one version to another, and *patching* exploitable implementations
* **Migrations: t**he process by which a contract is upgraded from an older version to a newer version
* **Module:** bespoke, standalone contracts used for the growth or operations of a company.  Technical teams can easily create new modules to suit their own needs or to sell to other companies.
* **Non-Core Contract:** contracts that a Mezzanine company relies on but are not part of the company's organizational hierarchy.  Non-core contracts are *not* redeployed upon the creation of a Mezzanine company.  They are upgradeable contracts.
* **Parent:** the node directly above a *child*.
* **Payroll Manager:** a module-like contract that manages the payroll of a Mezzanine company. It is deployed with each Mezzanine company and does not require approvals to spend funds
* **Patch:** the process of resetting an exploitable contract's implementation to a fixed version
* **Priced Round:** a type of equity financing that defines the rate at which ownership of the company (typically in the form of *preferred shares*) is exchanged for money.&#x20;
* **Protocol State:** defines whether or not certain functions in the Mezzanine protocol are executable.  The protocol state can be *Active, Paused,* or *Frozen,* where *Active* is the least restrictive while *Frozen* is the most restrictive. &#x20;
* **Seniority Level:** a set of assets in the capital stack.  Seniority levels are defined by a doubly linked list, the order of which determines their seniority. &#x20;
* **Token Timelock**: a module-like contract that is used to vest a company's shares. It is redeployed with each Mezzanine company. &#x20;
* **Treasury:** a Safe (formerly Gnosis Safe) multi-signature wallet.  Should hold the vast majority of a company's funds at any given point in time.  Funds and shares used for equity financing, payroll, and debt are spent directly from this contract.  Can insert modules and other departments at any other node across the organizatio&#x6E;*.*  Can manage the signers of any department and execute any admin-like functionality of any module in the organization.
* **Upgrades:** the changing of a proxy's implementation to another implementation. &#x20;


# Source Code

The following sections were generated directly from the NatSpec included in the Solidity Files.  Each section links the source file that the section was generated from.  It is recommended to look at the source file to clear any confusion.

Many base contracts were excluded from the Gitbook.  The source code should be reviewed to clear any confusion regarding base contracts.


# Core

The following sections relate to *Core* contracts.  *Core* contracts are deployed by the Mezz Deployer using [EIP-1967 upgradeable proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Proxy) and [EIP-1167 minimal proxies](https://eips.ethereum.org/EIPS/eip-1167).


# Base

The following documentation describes *base* contracts that only *core* contracts inherit


# Team

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

**Inherits:** Initializable, ContextUpgradeable, StateAware, Patchable, Safe, ITeam

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

A base contract that coordinates a group of people making decisions, such as a Treasury or Department. Teams directly inherit from Safe, making them capable of executing arbitrary transactions given the proper authorization by its signers.

*Safe does not implement upgrade-friendly storage. Therefore, it is of utter importance that all upgradeable contracts that inherit from 'Team' use ERC7201 namespaced storage to prevent potential storage collisions. Some may be curious why we are not creating a '$' var when accessing ERC7201 storage. This is because Safe and the other dependencies used take up an enormous amount of contract size. Therefore, we are heavily optimizing for contract size rather than readability or gas efficiency*

## State Variables

### TeamStorageLocation

```solidity
bytes32 private constant TeamStorageLocation = 0xc7b1874f9540775a2ee3dd2e2c7ee421a4027040e4b76eb32ebb1dabf89ce400;
```

## Functions

### \_getTeamStorage

```solidity
function _getTeamStorage() internal pure returns (TeamStorage storage $);
```

### constructor

```solidity
constructor(address _mezzHub, address _mezzMigrator) StateAware(_mezzHub) Patchable(_mezzMigrator);
```

### onlyChild

*Reverts if the caller is not a child*

```solidity
modifier onlyChild();
```

### onlyChildOrThis

*Reverts if the caller is not a child or 'this'*

```solidity
modifier onlyChildOrThis();
```

### \_\_Team\_init

*Initializes the Safe's state and sets the guard*

```solidity
function __Team_init(address[] memory _owners, uint256 _threshhold, address initGuard) internal onlyInitializing;
```

**Parameters**

| Name          | Type        | Description                |
| ------------- | ----------- | -------------------------- |
| `_owners`     | `address[]` | The initial signers/owners |
| `_threshhold` | `uint256`   | The initial threshold      |
| `initGuard`   | `address`   | The guard to set           |

### execMultipleTransactions

A function to execute multiple tranctions atomically via the Team's Safe fuctionality.

*The 'target' of the call is 'this' but the function selector of each 'transaction' must be 'execTransaction' The function, itself, is not pausable or freezable. However, 'execTransaction' is freezable, meaning this function will revert if the protocol state is frozen or if the implementation is frozen.*

```solidity
function execMultipleTransactions(bytes[] memory transactions) public payable virtual returns (bool[] memory);
```

**Parameters**

| Name           | Type      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| -------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `transactions` | `bytes[]` | The transactions to execute. Each transaction must be an encoded version of 'execTransaction'. [Reference](https://github.com/safe-global/safe-contracts/blob/be0c330000c85e1f338cafa1f64324b899bf1ab9/contracts/Safe.sol#L119-L150). If any other function selector is passed, the transaction will revert. It should be noted that the operation type of the transaction must be a call, since delegate calls have been disabled via Mezz Guards On a frontend, '0' must be passed to indicate a 'Call'. [Reference](https://github.com/safe-global/safe-contracts/blob/f03dfae65fd1d085224b00a10755c509a4eaacfe/contracts/common/Enum.sol#L9-L12). |

**Returns**

| Name     | Type     | Description                                                                                                                                                                                               |
| -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `bool[]` | An array of booleans that indicate whether or not each transaction was successful Each element of the array should be 'true', since any call to this function will revert if any of the transactions fail |

### execTransaction

Same as safe's execTransaction, except uses the 'freezable' modifier

[*Reference*](https://github.com/safe-global/safe-contracts/blob/be0c330000c85e1f338cafa1f64324b899bf1ab9/contracts/Safe.sol#L119-L150)*.*

```solidity
function execTransaction(
    address to,
    uint256 value,
    bytes calldata data,
    Enum.Operation operation,
    uint256 safeTxGas,
    uint256 baseGas,
    uint256 gasPrice,
    address gasToken,
    address payable refundReceiver,
    bytes memory signatures
) public payable virtual override freezable returns (bool);
```

### execTransactionFromModule

*Safe modules have been disabled, since they could arbitrarily change the signers of a team*

```solidity
function execTransactionFromModule(address, uint256, bytes memory, Enum.Operation)
    public
    virtual
    override
    returns (bool);
```

### manageOwners

A function to manage the signers of a Gnosis Safe.

*Makes external, authorized calls on address(this) that are normally blocked by Mezz Guards. This function is overridden and access-controlled such that the caller must be a Treasury's governor or a department's ancestor Refer to Constants.sol for the given function selectors that can be used as an 'action'*

```solidity
function manageOwners(bytes4 owners, bytes memory params) external virtual;
```

**Parameters**

| Name     | Type     | Description                                        |
| -------- | -------- | -------------------------------------------------- |
| `owners` | `bytes4` |                                                    |
| `params` | `bytes`  | The abi-encoded parameters to pass to the function |

### swapGuard

A function to swap the guard of a team contract.

*Makes external, authorized calls on address(this) that are normally blocked by Mezz Guards. This function is overridden and access-controlled such that the caller must be a Treasury's governor or a department's ancestor*

```solidity
function swapGuard(bytes32 guardCoreId, bytes memory params) external virtual returns (address);
```

### insertChild

Inserts 'childToInsert' to the '\_children' set. 'childToInsert' must support the module or department interface Will revert if 'childToInsert' is already in the '\_children' set

```solidity
function insertChild(address departmentToInsert) external virtual authorized freezable;
```

### removeChild

Removes 'childToRemove' from the '\_children' set. Will revert if 'childToRemove' is not in the '\_children' set

```solidity
function removeChild(address departmentToRemove) external virtual authorized freezable;
```

### getChildren

Returns all children as an address array

```solidity
function getChildren() public view returns (address[] memory);
```

### getSolvency

Returns the 'solvency' of this as defined by the DataTypes.Solvency enum

```solidity
function getSolvency() public view returns (DataTypes.Solvency);
```

### getParent

Returns the parent of 'this'. If 'this' is a department or module, returns the team that directly controls 'this'. If 'this' is the Treasury, returns the sentinel parent, which is address(0x1)

```solidity
function getParent() public view virtual returns (address);
```

**Returns**

| Name     | Type      | Description                                                                              |
| -------- | --------- | ---------------------------------------------------------------------------------------- |
| `<none>` | `address` | The parent, which is either the treasury, a department, a module, or the sentinel parent |

### name

Returns the name of 'this', which is a string

```solidity
function name() public view virtual returns (string memory);
```

### \_validateSolvent

*Reverts if the company state is not solvent*

```solidity
function _validateSolvent() internal view virtual;
```

### \_isCallerChild

*Returns true if the caller is a 'child'*

```solidity
function _isCallerChild() internal view virtual returns (bool);
```

### \_validateCallerIsChild

*Reverts if the caller is not a 'child' of 'this'*

```solidity
function _validateCallerIsChild() internal view virtual;
```

### \_validateCallerIsChildOrThis

*Reverts if the caller is not 'this' or a 'child' of 'this'*

```solidity
function _validateCallerIsChildOrThis() internal view virtual;
```

### \_validateLiquidating

*Reverts if the company state is not liquidating*

```solidity
function _validateLiquidating() internal view virtual;
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(MezzUUPSUpgradeable, IERC165)
    returns (bool);
```

### upgradeToAndCall

*Overridden 'upgradeToAndCall' from UUPSUpgradeable Validates that the 'data' is not to manage the owners and threshold, set the guard, or enable modules '\_authorizeUpgrade()' has been overridden in MezzUUPSUpgradeable such that this can only be called by the Mezz Migrator*

```solidity
function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual override onlyProxy;
```

### \_authorizePatch

*Overridden '\_authorizePatch' from Patchable. Validates 'data' is not used to manage the owners, threshold,*

*Overridden '\_authorizePatch' from Patchable. Validates 'data' is not used to manage the owners, threshold, set the guard, or enable modules*

```solidity
function _authorizePatch(bytes memory data) internal view virtual override;
```

## Structs

### TeamStorage

```solidity
struct TeamStorage {
    DataTypes.Solvency _solvency;
    EnumerableSet.AddressSet _children;
}
```


# TeamControlled

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

**Inherits:** Initializable, ContextUpgradeable, ITeamControlled

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

A base contract whose inheritors can enforce ownership-like access control. This access control is non-transferrable and cannot be renounced.

## State Variables

### TeamControlledStorageLocation

```solidity
bytes32 private constant TeamControlledStorageLocation =
    0xb816793abbf480753098fb767c6f1dcec3044cd562367c4739d88482505d6d00;
```

## Functions

### \_getTeamControlledStorage

```solidity
function _getTeamControlledStorage() internal pure returns (TeamControlledStorage storage $);
```

### onlyTeam

*Reverts if the caller is not the 'team'*

```solidity
modifier onlyTeam();
```

### onlyTeamOrAncestor

*Reverts if the caller is not the 'team' or its ancestor*

```solidity
modifier onlyTeamOrAncestor();
```

### \_\_TeamControlled\_init

*Sets the '\_team' variable and validate that it supports the ITeam interface*

```solidity
function __TeamControlled_init(address initTeam) internal virtual onlyInitializing;
```

### team

Returns the address of the team, which act similar to an 'owner' of the contract

```solidity
function team() public view virtual returns (address);
```

### \_isCallerTeam

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

### \_validateCallerIsTeam

*Reverts if the caller is not the 'team'*

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

### \_validateCallerIsTeamOrAncestor

*Reverts if the caller is not the 'team' or an ancestor of the 'team'*

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

## Structs

### TeamControlledStorage

```solidity
struct TeamControlledStorage {
    address _team;
}
```


# AdminControlled

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

**Inherits:** BoardControlled, IAdminControlled

**Author:** Daniel Yamagata

A base contract that is inherited by contracts meant to be controlled by a company's board of directors and a set of admins

## State Variables

### AdminControlledStorageLocation

```solidity
bytes32 private constant AdminControlledStorageLocation =
    0xe8d3a2e05e64290a0f2256f86af6161ca7eebf433b9b144d23028b2415816200;
```

## Functions

### \_getAdminControlledStorage

```solidity
function _getAdminControlledStorage() internal pure returns (AdminControlledStorage storage $);
```

### onlyAdmin

*Reverts if the caller is not the board or an admin*

```solidity
modifier onlyAdmin();
```

### addAdmin

Adds 'adminToAdd' to the list of admins

```solidity
function addAdmin(address adminToAdd) external onlyBoard;
```

### removeAdmin

Removes 'adminToRemove' from the list of admins

```solidity
function removeAdmin(address adminToRemove) external onlyBoard;
```

### isAdmin

Returns true if the 'adminToCheck' is part of the admins set

```solidity
function isAdmin(address adminToCheck) public view returns (bool);
```

### getAdmins

Returns the list of admins

```solidity
function getAdmins() public view returns (address[] memory);
```

### \_validateCallerIsBoardOrAdmin

*Reverts if the caller is not the board or an admin*

```solidity
function _validateCallerIsBoardOrAdmin() internal view virtual;
```

### \_isCallerBoardOrAdmin

*Returns true if the caller is the board or an admin*

```solidity
function _isCallerBoardOrAdmin() internal view virtual returns (bool);
```

## Structs

### AdminControlledStorage

```solidity
struct AdminControlledStorage {
    EnumerableSet.AddressSet _admins;
}
```


# Credentialed

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

**Inherits:** ERC165Upgradeable, ICredentialed

**Author:** Daniel Yamagata & Naveen Ailawadi

A base contract that requires implementers to define a core identifier and version

*Contracts must be credentialed to be set in the Mezz Migrator*

## Functions

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual returns (uint256);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(ERC165Upgradeable, IERC165)
    returns (bool);
```


# MezzUUPSUpgradeable

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

**Inherits:** Credentialed, UUPSUpgradeable, IMezzUUPSUpgradeable

**Author:** Daniel Yamagata & Naveen Ailawadi

A base contract inherited by user-facing, upgradeable core contract

*All calls to 'upgradeToAndCall()' must be made by the Mezz Migrator*

## State Variables

### MEZZ\_MIGRATOR

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

## Functions

### constructor

```solidity
constructor(address _mezzMigrator);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId) public view virtual override(Credentialed, IERC165) returns (bool);
```

### \_authorizeUpgrade

*Called in UUPSUpgradeable's upgradeToAndCall(...). Overridden such that the caller must be MEZZ\_MIGRATOR.*

```solidity
function _authorizeUpgrade(address) internal virtual override;
```


# MezzShares

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

**Inherits:** StateAware, VotesDelegator, Asset, ModifiedERC20VotesUpgradeable, IMezzShares

**Author:** Daniel Yamagata & Naveen Ailawadi

A base contract for share classes in the Mezzanine Protocol. Each share class has a voting weight, which is used to calculate voting power in governance. The 'governor' of a company must authorize shares before they can be issued. Shares can only be issued by the company's treasury, whose signers are the board of directors.

*This contract is intended to be inherited and extended by specific share types. The clock() and CLOCK\_MODE() differ from ERC20VotesUpgradeable. Mezz Shares uses block.timestamp in place of block.number This is due to the fact that block production times vary by chain, making block.number an unreliable measure of time for this implementation. \_transferVotingUnits() has been overridden such that \_totalCheckpoints is decremented when shares are transferred to the treasury and incremented when shares are transferred from the treasury*

## State Variables

### MezzSharesStorageLocation

```solidity
bytes32 private constant MezzSharesStorageLocation = 0x6829dd64f0945a99a0d73ec15476b4eceeec289ab2b16126da6305eb5684a600;
```

## Functions

### \_getMezzSharesStorage

```solidity
function _getMezzSharesStorage() internal pure returns (MezzSharesStorage storage $);
```

### constructor

```solidity
constructor(address _mezzHub) StateAware(_mezzHub);
```

### \_\_MezzShares\_init

```solidity
function __MezzShares_init(address initTreasury, uint256 initVotingWeight) internal onlyInitializing;
```

### treasury

Returns the address of the treasury, whose signers are the company's board of directors

```solidity
function treasury() public view override(BoardControlled, VotesDelegator, IBoardControlled) returns (ITreasury);
```

### authorizedShares

Returns the number of authorized shares

```solidity
function authorizedShares() public view virtual override returns (uint256);
```

**Returns**

| Name     | Type      | Description                     |
| -------- | --------- | ------------------------------- |
| `<none>` | `uint256` | The number of authorized shares |

### votingWeight

Returns the voting weight of the shares

*'votingWeight' is how much voting power each share has in governance*

```solidity
function votingWeight() external view virtual returns (uint256);
```

**Returns**

| Name     | Type      | Description       |
| -------- | --------- | ----------------- |
| `<none>` | `uint256` | The voting weight |

### authorizeShares

Authorizes the specified number of shares

*Increments 'authorizedShares' by 'amount'. Only callable by the Mezz Governor*

```solidity
function authorizeShares(uint256 amount) external virtual onlyMezzGovernance;
```

**Parameters**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `amount` | `uint256` | The number of shares to authorize |

### issueShares

Issues a number of shares to an account or vests shares to the account via the Token Timelock

*Decrements 'authorizedShares' by 'value'. Only callable by the Treasury. This function will revert if 'duration' is zero and 'cliff', 'initialUnlock', 'startDate, and 'obligatory' are not null*

```solidity
function issueShares(
    address recipient,
    uint256 amount,
    uint32 duration,
    uint32 cliff,
    uint256 initialUnlock,
    uint48 startDate,
    bool obligatory
) external virtual onlyBoard returns (uint256);
```

**Parameters**

| Name            | Type      | Description                                                             |
| --------------- | --------- | ----------------------------------------------------------------------- |
| `recipient`     | `address` | The account to issue or vest shares to                                  |
| `amount`        | `uint256` | The number of shares to issue                                           |
| `duration`      | `uint32`  | The duration of the vesting period in seconds                           |
| `cliff`         | `uint32`  | The time in seconds after the start date that the initial unlock occurs |
| `initialUnlock` | `uint256` | The number of shares that unlock at the cliff                           |
| `startDate`     | `uint48`  | The start date of the vesting period as a Unix-timestamp in seconds     |
| `obligatory`    | `bool`    | Whether the shares' vesting is obligatory or not                        |

**Returns**

| Name     | Type      | Description                                                           |
| -------- | --------- | --------------------------------------------------------------------- |
| `<none>` | `uint256` | The token timelock's address if the shares are vested, otherwise zero |

### burn

Burns the sender's shares by 'amount'

*Called by the Token Timelock when vesting is canceled*

```solidity
function burn(uint256 amount) external virtual;
```

**Parameters**

| Name     | Type      | Description                  |
| -------- | --------- | ---------------------------- |
| `amount` | `uint256` | The number of shares to burn |

### updateDelegate

Updates the delegate of 'delegator' from 'fromDelegate' to 'toDelegate'. Only callable by the Delegate Registry

```solidity
function updateDelegate(address account, address oldDelegatee, address newDelegatee)
    external
    virtual
    override(VotesDelegator, IVotesDelegator)
    onlyDelegateRegistry;
```

### outstandingSupply

Returns the number of shares outstanding. The outstanding shares are the total supply minus the treasury shares and shares that are vesting in the Token Timelock.

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

### fullyDilutedSupply

Returns the fully diluted supply of shares, which include the number of authorized shares

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

### delegates

Returns the delegate for 'account' that is set in the delegate registry

```solidity
function delegates(address account) public view virtual override(IVotes, ModifiedVotesUpgradeable) returns (address);
```

### delegateBySig

*Overridden 'delegateBySig()' such that it always revert*

```solidity
function delegateBySig(address, uint256, uint256, uint8, bytes32, bytes32)
    public
    virtual
    override(IVotes, ModifiedVotesUpgradeable);
```

### delegate

*Overridden 'delegate()' such that it always reverts*

```solidity
function delegate(address) public virtual override(IVotes, ModifiedVotesUpgradeable);
```

### \_delegate

```solidity
function _delegate(address, address) internal virtual override;
```

### name

Returns the name of the asset as a string

```solidity
function name() public view virtual override(Asset, IAsset, ERC20Upgradeable) returns (string memory);
```

### symbol

Returns the symbol of the asset as a string

```solidity
function symbol() public view virtual override(Asset, IAsset, ERC20Upgradeable) returns (string memory);
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```

### removable

Returns true if the total supply of shares is zero, false otherwise

*This function is queried by the treasury and capital stack to see if shares can be removed. To get a total supply of zero, all outstanding shares should be burned*

```solidity
function removable() public view virtual override(Asset, IAsset) returns (bool);
```

### clock

Returns the block.timestamp as a uint48

*EIP-6372 implementation. block.timestamp is used over block.number*

```solidity
function clock() public view virtual override(ModifiedVotesUpgradeable, VotesDelegator, IERC6372) returns (uint48);
```

### CLOCK\_MODE

Returns a URL-query-like string as specified in EIP-6372

*Timestamp is used over block.number*

```solidity
function CLOCK_MODE()
    public
    view
    virtual
    override(ModifiedVotesUpgradeable, VotesDelegator, IERC6372)
    returns (string memory);
```

### \_getVotingUnits

```solidity
function _getVotingUnits(address account) internal view virtual override returns (uint256);
```

### \_maxSupply

```solidity
function _maxSupply() internal view virtual override returns (uint256);
```

### \_update

*Override \_update(...), which is used on transfers in OZ's ERC20Votes implementation, such that delegatation is automatically completed for the receiver, if not already set*

```solidity
function _update(address from, address to, uint256 value) internal virtual override;
```

**Parameters**

| Name    | Type      | Description                                             |
| ------- | --------- | ------------------------------------------------------- |
| `from`  | `address` | The address from which the tokens are being transferred |
| `to`    | `address` | The address to which the tokens are being transferred   |
| `value` | `uint256` | The amount of tokens being transferred                  |

### \_transferVotingUnits

*Overridden \_transferVotingUnits() from OpenZeppelin's VotesUpgradeable.sol Decrements \_totalCheckpoints when shares are transferred to the treasury Increments \_totalCheckpoints when shares are transferred from the treasury*

```solidity
function _transferVotingUnits(address from, address to, uint256 amount) internal virtual override;
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId) public view virtual override(Asset, IERC165) returns (bool);
```

## Structs

### MezzSharesStorage

```solidity
struct MezzSharesStorage {
    uint256 _authorizedShares;
    uint256 _votingWeight;
}
```


# CommonShares

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

**Inherits:** MezzShares, ICommonShares

**Author:** Daniel Yamagata & Naveen Ailawadi

Common shares are the most basic type of shares in the Mezzanine Protocol. Common shares will always have a votign weight of one and can be initialized with a number of authorized shares

*This contract is intended to be deployed by the Mezz Deployer. Each company in Mezzanine can only have one class of common shares*

## Functions

### constructor

```solidity
constructor(address _mezzHub) MezzShares(_mezzHub);
```

### init

Initializes the asset state in a bespoke manner.

```solidity
function init(address initTreasury, bytes memory params) external virtual override(Asset, IAsset) initializer;
```

**Parameters**

| Name           | Type      | Description                                      |
| -------------- | --------- | ------------------------------------------------ |
| `initTreasury` | `address` |                                                  |
| `params`       | `bytes`   | The bespoke abi-encoded initialization arguments |

### \_\_CommonShares\_init

*Validates and sets the initial authorized shares*

```solidity
function __CommonShares_init(address initTreasury, bytes memory params) internal virtual onlyInitializing;
```

### assetClass

Returns the 'AssetClass' of the asset as a uint8, defined by the DataTypes.AssetClass enum

```solidity
function assetClass() public pure virtual override(Asset, IAsset) returns (uint8);
```

### name

Returns the name of the asset as a string

```solidity
function name() public view override(MezzShares, IAsset) returns (string memory);
```

### symbol

Returns the symbol of the asset as a string

```solidity
function symbol() public view override(MezzShares, IAsset) returns (string memory);
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(MezzShares, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(MezzShares, ICredentialed) returns (uint256);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId) public view virtual override(MezzShares, IERC165) returns (bool);
```


# PreferredShares

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

**Inherits:** MezzShares, IPreferredShares

**Author:** Daniel Yamagata & Naveen Ailawadi

Preferred shares are similar to Common Shares but keep track of a liquidation preference value and have a bespoke voting weight. They take preference over common shares during liquidation. Given there is a sufficient balance held by a company's treasury, Preferred Shares will receive a fixed amount of the denomination asset per share before any of the company's denomination asset is distributed pro-rata to equity holders.

*This contract is intended to be deployed by a Treasury instance via the Mezz Deployer*

## State Variables

### PreferredSharesStorageLocation

```solidity
bytes32 private constant PreferredSharesStorageLocation =
    0x4c4d55bf5bf083c0390e26954b0513b7e3733262a658373aa44cfed72f244700;
```

## Functions

### \_getPreferredSharesStorage

```solidity
function _getPreferredSharesStorage() internal pure returns (PreferredSharesStorage storage $);
```

### constructor

```solidity
constructor(address _mezzHub) MezzShares(_mezzHub);
```

### init

Initializes the asset state in a bespoke manner.

```solidity
function init(address initTreasury, bytes memory params) external virtual override(IAsset, Asset) initializer;
```

**Parameters**

| Name           | Type      | Description                                      |
| -------------- | --------- | ------------------------------------------------ |
| `initTreasury` | `address` |                                                  |
| `params`       | `bytes`   | The bespoke abi-encoded initialization arguments |

### \_\_PreferredShares\_init

```solidity
function __PreferredShares_init(address initTreasury, bytes memory params) internal virtual onlyInitializing;
```

### liquidationPreferenceValue

Returns the liquidation preference value per share. The value corresponds to how much of the denomination asset per share will be distributed during a company's liquidation

```solidity
function liquidationPreferenceValue() public view virtual returns (uint256);
```

**Returns**

| Name     | Type      | Description                                |
| -------- | --------- | ------------------------------------------ |
| `<none>` | `uint256` | The liquidation preference value per share |

### assetClass

Returns the 'AssetClass' of the asset as a uint8, defined by the DataTypes.AssetClass enum

```solidity
function assetClass() public pure virtual override(Asset, IAsset) returns (uint8);
```

### name

Returns the name of the asset as a string

```solidity
function name() public view override(MezzShares, IAsset) returns (string memory);
```

### symbol

Returns the symbol of the asset as a string

```solidity
function symbol() public view override(MezzShares, IAsset) returns (string memory);
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(MezzShares, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(MezzShares, ICredentialed) returns (uint256);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId) public view virtual override(MezzShares, IERC165) returns (bool);
```

## Structs

### PreferredSharesStorage

```solidity
struct PreferredSharesStorage {
    uint256 _liquidationPreferenceValue;
}
```


# Treasury

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

**Inherits:** ITreasury, Team

**Author:** Daniel Yamagata & Naveen Ailawadi

A Safe-like contract whose signers are a company's board of directors. A Mezzanine company resembles a tree data structure. The 'Treasury' is the root node of the tree, while 'departments' and 'modules' are internal and leaf nodes. A treasury should hold nearly all assets of a company. Funds can be spent recursively by departments and modules given there are sufficcient approvals and balances. The entirety of a company can be queried either directly from the treasury or via a tree traversal algorithm

## State Variables

### TreasuryStorageLocation

```solidity
bytes32 private constant TreasuryStorageLocation = 0xa29865ab22e3c13f4e3fda97514b6fba0b0844305463cbe6cf02bc044b877500;
```

## Functions

### \_getTreasuryStorage

```solidity
function _getTreasuryStorage() internal pure returns (TreasuryStorage storage $);
```

### constructor

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

### onlyMezzGovernance

```solidity
modifier onlyMezzGovernance();
```

### onlyPayrollManager

```solidity
modifier onlyPayrollManager();
```

### init

```solidity
function init(DataTypes.TreasuryInitArgs memory initArgs) external virtual initializer;
```

### \_\_Treasury\_init

```solidity
function __Treasury_init(DataTypes.TreasuryInitArgs memory initArgs) internal virtual onlyInitializing;
```

### capitalStack

Returns the address of the company's capital stack

```solidity
function capitalStack() public view returns (address);
```

### delegateRegistry

Returns the address of the company's delegate registry

```solidity
function delegateRegistry() public view returns (address);
```

### denominationAsset

Returns the address of the denomination asset

*All debt by the company will be recorded in terms of the denomination asset This value is immutable*

```solidity
function denominationAsset() public view returns (address);
```

### getCommonShares

Returns the address of the company's common shares

*A treasury will only have a single set of common shares*

```solidity
function getCommonShares() public view returns (address);
```

### getGovernor

Returns the address of the Governor

*The Governor is able to manage the signers of the Treasury*

```solidity
function getGovernor() public view returns (address);
```

### getTokenTimelock

Returns the address of the Token Timelock

*Used by Mezz Shares to issue and vest shares atomically*

```solidity
function getTokenTimelock() public view returns (address);
```

### getPayrollManager

Returns the address of the Payroll Manager

*The Payroll Manager is a shortbound ERC721 contract that manages the payroll of employees. It is able to arbitrarily spend money and common shares from the treasury without approvals. It is controlled by the board of directors (i.e. the Treasury) and a set of admins, who are set by the board*

```solidity
function getPayrollManager() public view returns (address);
```

### isAddingAsset

Returns true if the treasury is adding an asset, false otherwise.  A callback used by the capital stack to prevent the treasury from arbitrarily adding an asset to the capital stack

```solidity
function isAddingAsset() public view returns (bool);
```

### isRemovingAsset

Returns true if the treasury is removing an asset, false otherwise. A callback used by the capital stack to prevent the treasury from arbitrarily removing an asset from the capital stack

```solidity
function isRemovingAsset() public view returns (bool);
```

### manageOwners

A function to manage the signers of a Gnosis Safe.

*Makes external, authorized calls on address(this) that are normally blocked by Mezz Guards. This function is overridden and access-controlled such that the caller must be a Treasury's governor or a department's ancestor. Refer to Constants.sol for the given function selectors that can be used as an 'action'*

```solidity
function manageOwners(bytes4 action, bytes memory params)
    external
    virtual
    override(Team, ITeam)
    onlyMezzGovernance
    freezable;
```

**Parameters**

| Name     | Type     | Description                                        |
| -------- | -------- | -------------------------------------------------- |
| `action` | `bytes4` | The function selector of the function to call      |
| `params` | `bytes`  | The abi-encoded parameters to pass to the function |

### swapGuard

A function to swap the guard of a team contract.

*Makes external, authorized calls on address(this) that are normally blocked by Mezz Guards. This function is overridden and access-controlled such that the caller must be a Treasury's governor or a department's ancestor*

```solidity
function swapGuard(bytes32 guardCoreId, bytes memory params)
    external
    virtual
    override(Team, ITeam)
    onlyMezzGovernance
    freezable
    returns (address);
```

### insertChild

Inserts 'childToInsert' to the '\_children' set. 'childToInsert' must support the module or department interface. Will revert if 'childToInsert' is already in the '\_children' set

```solidity
function insertChild(address childToInsert) external virtual override(Team, ITeam) authorized pausable;
```

### removeChild

Removes 'childToRemove' from the '\_children' set. Will revert if 'childToRemove' is not in the '\_children' set

```solidity
function removeChild(address childToRemove) external virtual override(Team, ITeam) authorized freezable;
```

### changeGovernor

Deploys and initializes a new governor. Sets the new governor accordingly

*Changes the current governor to a new one associated with 'governorCoreId' A treasury cannot change its governor to one with the same core ID*

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

**Parameters**

| Name             | Type      | Description                                                              |
| ---------------- | --------- | ------------------------------------------------------------------------ |
| `governorCoreId` | `bytes32` | The core ID of the governor to switch to                                 |
| `params`         | `bytes`   | Bespoke abi.encoded parameters to pass to the governor's init() function |

**Returns**

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

### addAssetToCapitalStack

Deploys an asset with 'assetCoreId' via the Mezz Deployer and adds it to the seniority level with 'seniorityLevelIndex' in the capital stack. If the asset supports the Mezz Shares interface, adds it to the company's shares. Adds a document to the Document Registry with 'assetDocumentName' and 'assetDocumentUri'. The 'owner' of the document will be the *capital stack*. The name and URI can be updated retroactively at any time.

```solidity
function addAssetToCapitalStack(
    bytes32 assetCoreId,
    uint256 seniorityLevelIndex,
    bytes memory params,
    string memory assetDocumentName,
    string memory assetDocumentUri
) external virtual authorized pausable returns (address);
```

**Parameters**

| Name                  | Type      | Description                                                               |
| --------------------- | --------- | ------------------------------------------------------------------------- |
| `assetCoreId`         | `bytes32` |                                                                           |
| `seniorityLevelIndex` | `uint256` |                                                                           |
| `params`              | `bytes`   | The bespoke abi.encoded parameters to pass to the asset's init() function |
| `assetDocumentName`   | `string`  |                                                                           |
| `assetDocumentUri`    | `string`  |                                                                           |

### removeAssetFromCapitalStack

Removes an asset from the capital stack. The 'removable()' function of 'assetToRemove()' must return true for this function to succeed. The conditions for removal are bespoke to each asset. For example, the total supply of a share class must be zero for it to be removed. If 'assetToRemove' supports the Mezz Shares interface, it will be removed from the company's shares. The document associated with the asset will be updated to null

```solidity
function removeAssetFromCapitalStack(address assetToRemove) external virtual authorized freezable;
```

### spendPayroll

Transfers an 'amount' of an 'asset' to the payroll module. Only callable by the payroll module. The asset must either be a whitelisted denomination asset or the company's common shares. Returns the amount of the asset paid to the recipient, inclusive of ERC20 transfer fees.

*This function bypasses all of the treasury's ERC20 allowances. This was designed in a manner to prevent the board from needing to manually setting approvals for payroll*

```solidity
function spendPayroll(address recipient, address asset, uint256 amount)
    external
    virtual
    onlyPayrollManager
    pausable
    returns (uint256);
```

**Parameters**

| Name        | Type      | Description                                  |
| ----------- | --------- | -------------------------------------------- |
| `recipient` | `address` | The recipient of the funds                   |
| `asset`     | `address` | The asset to pay the recipient in            |
| `amount`    | `uint256` | The amount of the asset to pay the recipient |

**Returns**

| Name     | Type      | Description                                                                                 |
| -------- | --------- | ------------------------------------------------------------------------------------------- |
| `<none>` | `uint256` | The amount paid, which takes into account any native ERC20 transfer fees built into 'asset' |

### spend

Transfers 'amount' of asset to the caller, who must be a child. Sends any set fees for the treasury implementation to the fee controller

```solidity
function spend(address asset, uint256 amount) external virtual onlyChild pausable;
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```

### name

Returns the name of 'this', which is a string

```solidity
function name() public view override(Team, ITeam) returns (string memory);
```

### symbol

Returns the symbol for the company

```solidity
function symbol() public view returns (string memory);
```

### getParent

Returns the parent of 'this'. If 'this' is a department or module, returns the team that directly controls 'this'. If 'this' is the Treasury, returns the sentinel parent, which is address(0x1)

```solidity
function getParent() public pure override(Team, IChild) returns (address);
```

**Returns**

| Name     | Type      | Description                                                                              |
| -------- | --------- | ---------------------------------------------------------------------------------------- |
| `<none>` | `address` | The parent, which is either the treasury, a department, a module, or the sentinel parent |

### getShares

Returns the addresses for the company's share classes as an address array

```solidity
function getShares() public view returns (address[] memory);
```

### isValidShares

Returns true if 'sharesToCheck' is a valid share class for the company, false otherwise

```solidity
function isValidShares(address sharesToCheck) public view returns (bool);
```

**Parameters**

| Name            | Type      | Description         |
| --------------- | --------- | ------------------- |
| `sharesToCheck` | `address` | The shares to check |

### outstandingSupply

Returns the summation of the outstanding supply for all share classes. This does not include any vesting or treasury shares

```solidity
function outstandingSupply() external view returns (uint256);
```

### fullyDilutedSupply

Returns the summation of the fully diluted supply for all share classes. This includes authorized, vesting, and treasury shares

```solidity
function fullyDilutedSupply() external view returns (uint256);
```

### \_validateCallerIsPayrollManager

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

### \_validateCallerIsGovernance

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

### \_authorizePatch

*Access control for 'resetToPatchedLatestVersion()'. Validation of 'data' is completd in Team.sol*

```solidity
function _authorizePatch(bytes memory data) internal view virtual override;
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId) public view virtual override(Team, IERC165) returns (bool);
```

## Structs

### TreasuryStorage

```solidity
struct TreasuryStorage {
    bool _addingAssetHook;
    bool _removingAssetHook;
    address _commonShares;
    address _denominationAsset;
    address _capitalStack;
    address _delegateRegistry;
    address _tokenTimelock;
    address _payrollManager;
    address _governor;
    string _name;
    string _symbol;
    EnumerableSet.AddressSet _shares;
}
```


# Department

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

**Inherits:** Team, IDepartment

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

A multi-signature wallet whose signers are determined by its ancestors. A department can transfer funds recursively from the treasury to themselves, given there is sufficient approvals and balances. An ancestor is a department or the treasury, which is higher in the organizational hierarchy than 'this'. Unlike the traditional definition, an 'ancestor' does not include 'this', itself.

## State Variables

### DepartmentStorageLocation

```solidity
bytes32 private constant DepartmentStorageLocation = 0xbcbd9931e6c2b25760bd06d79dd059ceba389ce5a1832f868178693a75fc3c00;
```

## Functions

### \_getDepartmentStorage

```solidity
function _getDepartmentStorage() internal pure returns (DepartmentStorage storage $);
```

### constructor

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

### onlyAncestor

```solidity
modifier onlyAncestor();
```

### onlyAncestorOrAuthorized

*The msg.sender must be 'this' or an ancestor*

```solidity
modifier onlyAncestorOrAuthorized();
```

### init

Standardized init function that all departments must inherit

```solidity
function init(
    address initTreasury,
    address[] memory _owners,
    uint256 _threshhold,
    address initGuard,
    address initParent,
    bytes memory params
) external virtual;
```

**Parameters**

| Name           | Type        | Description                                                                                |
| -------------- | ----------- | ------------------------------------------------------------------------------------------ |
| `initTreasury` | `address`   | The address of the treasury                                                                |
| `_owners`      | `address[]` | The initial signers of the department's multisig                                           |
| `_threshhold`  | `uint256`   | The initial threshold of the department's multisig                                         |
| `initGuard`    | `address`   | The address of the guard contract, which should be deployed atomically with the department |
| `initParent`   | `address`   | The address of the department's parent                                                     |
| `params`       | `bytes`     | Any additional parameters that the department needs to initialize                          |

### \_\_Department\_init

*Sets the initial state for a department and validates inputs*

```solidity
function __Department_init(
    address initTreasury,
    address[] memory _owners,
    uint256 _threshold,
    address initGuard,
    address initParent,
    string memory initDepartmentName
) internal onlyInitializing;
```

### manageOwners

A function to manage the signers of a Gnosis Safe.

*Makes external, authorized calls on address(this) that are normally blocked by Mezz Guards. This function is overridden and access-controlled such that the caller must be a Treasury's governor or a department's ancestor Refer to Constants.sol for the given function selectors that can be used as an 'action'*

```solidity
function manageOwners(bytes4 functionSelector, bytes memory params)
    external
    virtual
    override(Team, ITeam)
    onlyAncestor
    freezable;
```

**Parameters**

| Name               | Type     | Description                                        |
| ------------------ | -------- | -------------------------------------------------- |
| `functionSelector` | `bytes4` |                                                    |
| `params`           | `bytes`  | The abi-encoded parameters to pass to the function |

### swapGuard

A function to swap the guard of a team contract. Deploys and initializes the guard via the Mezz Deployer.

*Makes external, authorized calls on address(this) that are normally blocked by Mezz Guards. This function is overridden and access-controlled such that the caller must be a Treasury's governor or a department's ancestor*

```solidity
function swapGuard(bytes32 guardCoreId, bytes memory params)
    external
    virtual
    override(Team, ITeam)
    onlyAncestor
    freezable
    returns (address);
```

### insertChild

Inserts 'childToInsert' to the '\_children' set. 'childToInsert' must support the module or department interface. Will revert if 'childToInsert' is already in the '\_children' set

```solidity
function insertChild(address departmentToInsert)
    external
    virtual
    override(Team, ITeam)
    freezable
    onlyAncestorOrAuthorized;
```

### spend

Recursively transfers an 'amount' of 'asset' from the treasury to the caller, who must be a descendant of the treasury Will revert if the treasury has insufficient funds or the ancestors of 'this' have insufficient approvals

```solidity
function spend(address asset, uint256 amount) external virtual freezable onlyChildOrThis;
```

### getParent

```solidity
function getParent() public view virtual override(Team, IChild) returns (address);
```

**Returns**

| Name     | Type      | Description                                                                              |
| -------- | --------- | ---------------------------------------------------------------------------------------- |
| `<none>` | `address` | The parent, which is either the treasury, a department, a module, or the sentinel parent |

### treasury

Returns the treasury as an ITreasury interface

```solidity
function treasury() public view returns (ITreasury);
```

### name

Returns the name of 'this', which is a string

```solidity
function name() public view override(Team, ITeam) returns (string memory);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId) public view virtual override(Team, IERC165) returns (bool);
```

### \_validateCallerIsAncestor

*Reverts if the caller is not an ancestor*

```solidity
function _validateCallerIsAncestor() internal view virtual;
```

### \_validateCallerIsTeamOrAncestor

*Reverts if the caller is not an ancestor or address(this)*

```solidity
function _validateCallerIsTeamOrAncestor() internal view virtual;
```

### upgradeToNewerVersion

Upgrades 'this' to a newer version via the MezzMigrator

*Only callable by 'this' or an ancestor*

```solidity
function upgradeToNewerVersion(uint256 newVersion, bytes memory data)
    public
    virtual
    onlyProxy
    onlyAncestorOrAuthorized;
```

### \_authorizePatch

*Access control for 'resetToPatchedLatestVersion()'. Validation of 'data' is completd in Team.sol*

```solidity
function _authorizePatch(bytes memory data) internal view override;
```

## Structs

### DepartmentStorage

```solidity
struct DepartmentStorage {
    ITreasury _treasury;
    address _parent;
    string _departmentName;
}
```


# GeneralDepartment

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

**Inherits:** Department

**Author:** Daniel Yamagata & Naveen Ailawadi

A simple department which solely inherits the base functionality

## Functions

### constructor

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

### init

Standardized init function that all departments must inherit

```solidity
function init(
    address initTreasury,
    address[] memory _owners,
    uint256 _threshhold,
    address initGuard,
    address initParent,
    bytes memory params
) external virtual override initializer;
```

**Parameters**

| Name           | Type        | Description                                                                                |
| -------------- | ----------- | ------------------------------------------------------------------------------------------ |
| `initTreasury` | `address`   | The address of the treasury                                                                |
| `_owners`      | `address[]` | The initial signers of the department's multisig                                           |
| `_threshhold`  | `uint256`   | The initial threshold of the department's multisig                                         |
| `initGuard`    | `address`   | The address of the guard contract, which should be deployed atomically with the department |
| `initParent`   | `address`   | The address of the department's parent                                                     |
| `params`       | `bytes`     | Any additional parameters that the department needs to initialize                          |

### \_\_GeneralDepartment\_init

*Sets the 'departmentName' and calls the department's internal init function. The 'name' of the contract will be the concatenation of the company name, the department name, and " Department". For example, if the company name is "Foo" and 'departmentName' is "Bar", the contract name will be "Foo Bar Department".*

```solidity
function __GeneralDepartment_init(
    address initTreasury,
    address[] memory _owners,
    uint256 _threshhold,
    address initGuard,
    address initParent,
    bytes memory params
) internal virtual onlyInitializing;
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```


# Module

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

**Inherits:** Initializable, ERC165Upgradeable, TeamControlled, IModule

**Author:** Daniel Yamagata & Naveen Ailawadi

A base contract for modules, which are 'children' of departments and treasuries with bespoke logic and spending capabilities

\*Modules should be deployed as proxies. If ERC1967 proxies, their storage layout should use EIP7201 storage slots Reference:

* [EIP7201](https://eips.ethereum.org/EIPS/eip-7201)
* [ERC1967 Proxies](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/b5a7f977d8a57b6854545522e36d91a0c11723cd/contracts/proxy/ERC1967/ERC1967Proxy.sol*)

## Functions

### constructor

```solidity
constructor();
```

### init

Initializes the state of the module. This initialization is bespoke to each module

```solidity
function init(address initTeam, bytes memory params) external virtual;
```

**Parameters**

| Name       | Type      | Description                                                                 |
| ---------- | --------- | --------------------------------------------------------------------------- |
| `initTeam` | `address` | The team that controls the module                                           |
| `params`   | `bytes`   | The abi-encoded params to be decoded and passed to the module's initializer |

### \_\_Module\_init

```solidity
function __Module_init(address initTeam) internal virtual onlyInitializing;
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(ERC165Upgradeable, IERC165)
    returns (bool);
```

### getParent

Returns the parent of 'this'. If 'this' is a department or module, returns the team that directly controls 'this'. If 'this' is the Treasury, returns the sentinel parent, which is address(0x1)

```solidity
function getParent() public view virtual returns (address);
```

**Returns**

| Name     | Type      | Description                                                                              |
| -------- | --------- | ---------------------------------------------------------------------------------------- |
| `<none>` | `address` | The parent, which is either the treasury, a department, a module, or the sentinel parent |


# EquityFinancingModule

[Git Source](https://github.com/EntreDevelopers-Lab-Inc/Mezz-Companies/blob/f7a3e84e3dd5bb33c4bd7f77283983f9e8ba20b2/src/core/modules/equity-financing/EquityFinancingModule.sol)

**Inherits:** MezzUpgradeableModule, IEquityFinancingModule

**Author:** Daniel Yamagata

A module that manages the equity financing of a company. Priced rounds are indexed at one

*The initial version of Mezzanine only enables a Treasury to have the equity financing module as a child. Future versions may support departments having their own equity financing modules. Additionally, other forms of equity financing will be added via upgrades*

## State Variables

### EquityFinancingModuleStorageLocation

```solidity
bytes32 private constant EquityFinancingModuleStorageLocation =
    0xd961ff105dce6f539fbf0ae0958698eac72f58f46f1375706a8de3e60e2e2f00;
```

## Functions

### \_getEquityFinancingModuleStorage

```solidity
function _getEquityFinancingModuleStorage() internal pure returns (EquityFinancingModuleStorage storage $);
```

### constructor

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

### init

Initializes the state of the module. This initialization is bespoke to each module

```solidity
function init(address initTeam, bytes memory) external virtual override(Module, IModule) initializer;
```

**Parameters**

| Name       | Type      | Description                       |
| ---------- | --------- | --------------------------------- |
| `initTeam` | `address` | The team that controls the module |
| `<none>`   | `bytes`   |                                   |

### \_\_EquityFinancingModule\_init

```solidity
function __EquityFinancingModule_init(address initTeam) internal virtual onlyInitializing;
```

### currentRoundIndex

If there are no priced rounds, returns 0. Otherwise, returns the current round's index

*'initTeam' must be a department or treasury*

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

### openPricedRound

Opens a Priced Round for the treasury of 'team' and returns the address of the new priced round

*Only callable by the 'team' or its ancestor(s)*

```solidity
function openPricedRound(DataTypes.PricedRoundInitArgs memory initArgs, address shares)
    external
    virtual
    onlyTeamOrAncestor
    pausable
    returns (address);
```

**Parameters**

| Name       | Type                            | Description                                                                                  |
| ---------- | ------------------------------- | -------------------------------------------------------------------------------------------- |
| `initArgs` | `DataTypes.PricedRoundInitArgs` | The arguments to initialize the priced round with. Validated within the priced round, itself |
| `shares`   | `address`                       | The shares to be distributed in the priced round                                             |

### getPricedRounds

Cache

```solidity
function getPricedRounds() public view virtual returns (address[] memory);
```

### getPricedRoundByIndex

If the priced round with 'roundIndex' does not exist, returns address(0). Otherwise, returns the address of the priced round with 'roundIndex'

```solidity
function getPricedRoundByIndex(uint256 roundIndex) public view virtual returns (address);
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```

### \_updateStateForCanceledRound

*Deletes a canceled priced round from the '\_pricedRoundByIndex' mapping and decrements the '\_nextPricedRoundIndex'*

```solidity
function _updateStateForCanceledRound(uint256 currentRoundIndexCache) internal;
```

### \_incrementCurrentRoundIndex

*Increments the '\_currentRoundIndex' and returns the new value*

```solidity
function _incrementCurrentRoundIndex() internal returns (uint256);
```

### \_decrementCurrentRoundIndex

*Decrements the '\_currentRoundIndex' and returns the new value*

```solidity
function _decrementCurrentRoundIndex() internal returns (uint256);
```

### \_isTeamDepartment

*Returns true if 'teamCache' supports the Department Interface, false otherwise*

```solidity
function _isTeamDepartment(address teamCache) internal view returns (bool);
```

### \_isTeamTreasury

*Returns true if 'teamCache' supports the Treasury Interface, false otherwise*

```solidity
function _isTeamTreasury(address teamCache) internal view returns (bool);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(MezzUpgradeableModule, IERC165)
    returns (bool);
```

## Structs

### EquityFinancingModuleStorage

```solidity
struct EquityFinancingModuleStorage {
    uint256 _currentRoundIndex;
    mapping(uint256 => address) _pricedRoundByIndex;
}
```


# CapitalStack

[Git Source](https://github.com/EntreDevelopers-Lab-Inc/Mezz-Companies/blob/f7a3e84e3dd5bb33c4bd7f77283983f9e8ba20b2/src/core/ancillary/capital-stack/CapitalStack.sol)

**Inherits:** StateAware, Patchable, BoardControlled, ICapitalStack

**Author:** Daniel Yamagata & Naveen Ailawadi

A smart contract that lays out the logic for the capital stack of a company. The capital stack is the foundation for the mergers, acquistions, recapitalization, and liquidation of companies in the Mezzanine protocol A capital stack is made up of:

* Seniority Levels
* Assets&#x20;

Each seniority level and asset is associated with an 'asset class'. An asset of a given class can be inserted into only one seniority level of the same class. There are three types of asset classes, defined by the following enum:

* 0: Null
* 1: Common Equity
* 2: Preferred Equity
* 3: Debt&#x20;

A seniority level or asset with asset class 'Null' is considered invalid and cannot be added to the stack. Seniority levels must be added, such that a new seniority level's asset class cannot be below the previous's asset class and cannot exceed the next's asset class. For example, a seniority level of 'Common Equity' cannot be inserted above 'Debt' Here is a visual example:

***

| Index | Asset Class      | Assets     |
| ----- | ---------------- | ---------- |
| 2     | Debt             | D, E, F, G |
| 3     | Preferred Equity | B, C       |
| 1     | Common Equity    | A          |

*Seniority levels are represented by a circular, doubly linked list. Their indexes are not assumed to be sequential*

## State Variables

### CapitalStackStorageLocation

```solidity
bytes32 private constant CapitalStackStorageLocation =
    0x36092dfc4ccd895585e40ef098e02e99f066e08bb0ed611f9c0eac213dfb8b00;
```

## Functions

### \_getCapitalStackStorage

```solidity
function _getCapitalStackStorage() internal pure returns (CapitalStackStorage storage $);
```

### constructor

```solidity
constructor(address _mezzHub, address _mezzMigrator) StateAware(_mezzHub) Patchable(_mezzMigrator);
```

### init

Initializes state, inserts a common equity seniority level, adds the common shares to the capital, and creates a document for the common shares in the document registry. Can only be called once

*Called atomically by the MezzDeployer during the deployment of a Mezz Instance*

```solidity
function init(address initTreasury, address commonShares) external virtual initializer;
```

**Parameters**

| Name           | Type      | Description                                  |
| -------------- | --------- | -------------------------------------------- |
| `initTreasury` | `address` | The treasury to be used by the capital stack |
| `commonShares` | `address` | The address of the common shares             |

### \_\_CapitalStack\_init

```solidity
function __CapitalStack_init(address commonShares) internal onlyInitializing;
```

### addSeniorityLevel

Adds a seniority level to the capital stack. Only callable by the company's board of directors, who are the signers of the treasury contract. Seniority levels in a capital stack follow specific rules in how they can be inserted: Each seniority level has an associated 'AssetClass' defined by the following enum:

* 0: Null
* 1: Common Equity
* 2: Preferred Equity
* 3: Debt

A seniority level cannot be inserted if the previous seniority level, associated with 'previousSeniorityLevelIndex', has a higher 'AssetClass' than the proposed seniority level. For example, a seniority level of Common Equity cannot be inserted above a seniority level of Preferred Equity. Once inserted, only assets of that given class can be added to the given seniority level. A Mezzanine company can insert seniority levels above or below seniority levels of the same asset class. For example, a seniority level of Preferred Equity can be inserted above or below another seniority level of Preferred Equity. A company may do this since these different levels may be treated differently during liquidation, recapitalization, etc. Seniority levels with new types of asset classes can be added easily via upgrades

```solidity
function addSeniorityLevel(uint256 previousSeniorityLevelIndex, uint8 proposedAssetClass)
    external
    virtual
    onlyBoard
    pausable
    returns (uint256);
```

**Parameters**

| Name                          | Type      | Description                                                                |
| ----------------------------- | --------- | -------------------------------------------------------------------------- |
| `previousSeniorityLevelIndex` | `uint256` | The index of the previous seniority level, which is the point of insertion |
| `proposedAssetClass`          | `uint8`   | The asset class of the proposed seniority level                            |

**Returns**

| Name     | Type      | Description                                     |
| -------- | --------- | ----------------------------------------------- |
| `<none>` | `uint256` | The index of the newly inserted seniority level |

### \_addSeniorityLevel

Adding a seniority level has four cases:

* (A) The list is empty. Should only be true during initialization
* (B) An insertion at the front of the list
  * 'previousSeniorityLevelIndex' is zero
* (C) An insertion at the back of the list
  * The 'next' of 'previousSeniorityLevelIndex' is zero
* (D) An insertion in the middle of the list

  * 'previousSeniorityLevelIndex' is greater than zero but its 'next' is not equal to zero&#x20;

  The sentinel acts both as a header and a tail. The 'next' of the sentinel indicates the 'front' of the list while the 'previous' of the sentinel indicates the 'back' of the list Cases (A) and (D) are handled the same. Cases are handled differently to optimize for SSTOREs

```solidity
function _addSeniorityLevel(uint256 previousSeniorityLevelIndex, uint8 proposedAssetClass) internal returns (uint256);
```

### \_addToFrontOfSeniorityLevelList

*Case (B): An insertion at the front of the list*

```solidity
function _addToFrontOfSeniorityLevelList(
    uint256 seniorityLevelIndexToAdd,
    uint8 proposedAssetClass,
    uint256 oldNextIndex,
    DataTypes.SeniorityLevel storage oldNextSeniorityLevelPointer,
    CapitalStackStorage storage $
) internal virtual;
```

### \_addToBackOfSeniorityLevelList

*Case (C): An insertion at the back of the list*

```solidity
function _addToBackOfSeniorityLevelList(
    uint256 seniorityLevelIndexToAdd,
    uint8 proposedAssetClass,
    uint256 previousSeniorityLevelIndex,
    DataTypes.SeniorityLevel storage previousSeniorityLevelPointer,
    CapitalStackStorage storage $
) internal virtual;
```

### \_addToMiddleOfSeniorityLevelList

*Cases (A) and (D): An insertion in an empty list or in the middle of the list, respectively*

```solidity
function _addToMiddleOfSeniorityLevelList(
    uint256 seniorityLevelIndexToAdd,
    uint8 proposedAssetClass,
    uint256 previousSeniorityLevelIndex,
    uint256 oldNextIndex,
    DataTypes.SeniorityLevel storage previousSeniorityLevelPointer,
    DataTypes.SeniorityLevel storage oldNextSeniorityLevelPointer,
    CapitalStackStorage storage $
) internal virtual;
```

### removeSeniorityLevel

Removes a seniority level with 'seniorityLevelIndexToRemove' from the capital stack. Only callable by the company's board of directors, who are the signers of the Treasury. The seniority level must be empty, meaning it contains no assets.

```solidity
function removeSeniorityLevel(uint256 seniorityLevelIndexToRemove) external virtual onlyBoard freezable;
```

**Parameters**

| Name                          | Type      | Description                                |
| ----------------------------- | --------- | ------------------------------------------ |
| `seniorityLevelIndexToRemove` | `uint256` | The index of the seniority level to remove |

### addAssetToSeniorityLevel

Adds an asset to a seniority level. Only callable by the company's board of directors, who are the signers of the Treasury The asset must have the same 'AssetClass' as the seniority level it is being added to. This function adds a document to the document registry that is associated with the asset. It can be updated at any time. An asset can only be part of one seniority level and cannot be moved retroactively to a different seniority level.

*A treasury cannot call this function with its multi-sig functionality but instead must call the 'addAssetToCapitalStack' function*

```solidity
function addAssetToSeniorityLevel(
    uint256 seniorityLevelIndex,
    address assetToAdd,
    string memory assetDocumentName,
    string memory assetDocumentUri
) external virtual onlyBoard pausable returns (uint256);
```

**Parameters**

| Name                  | Type      | Description                                          |
| --------------------- | --------- | ---------------------------------------------------- |
| `seniorityLevelIndex` | `uint256` | The index of the seniority level to add the asset to |
| `assetToAdd`          | `address` |                                                      |
| `assetDocumentName`   | `string`  | The name of the asset document                       |
| `assetDocumentUri`    | `string`  | The URI of the asset document                        |

**Returns**

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `<none>` | `uint256` | The document index for the asset |

### \_addAssetToSeniorityLevel

*Adds an asset to the seniority level at 'seniorityLevelIndex' and creates a document for the asset*

```solidity
function _addAssetToSeniorityLevel(
    uint256 seniorityLevelIndex,
    address assetToAdd,
    string memory assetDocumentName,
    string memory assetDocumentUri
) internal virtual returns (uint256);
```

**Returns**

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `<none>` | `uint256` | The document index for the asset |

### removeAsset

Removes an asset from the capital stack. Only callable by the company's board of directors, who are the signers of the Treasury. A company cannot remove their initial common shares from the capital stack. All Mezz assets must implement a 'removable()' function that returns a bool indicating the asset's removability upon certain conditions. For example, Mezz shares are not removable if their total supply is greater than zero. If the 'removable()' of 'assetToRemove' returns false, this function will revert

*A treasury cannot call this function with its multi-sig functionality but instead must call the 'removeAssetFromCapitalStack' function*

```solidity
function removeAsset(address assetToRemove) external onlyBoard freezable;
```

**Parameters**

| Name            | Type      | Description                        |
| --------------- | --------- | ---------------------------------- |
| `assetToRemove` | `address` | The address of the asset to remove |

### updateAssetDocument

Updates an asset's document in the document registry

```solidity
function updateAssetDocument(address asset, string memory updatedDocumentName, string memory updatedDocumentUri)
    public
    virtual
    returns (uint256);
```

**Returns**

| Name     | Type      | Description                                                          |
| -------- | --------- | -------------------------------------------------------------------- |
| `<none>` | `uint256` | The new version of the document, which is originally indexed at zero |

### getSeniorityLevelInfo

Returns information regarding a seniority level as a 'DataTypes.SeniorityLevelInfo' struct

*Returns an empty struct if the seniority level does not exist*

```solidity
function getSeniorityLevelInfo(uint256 seniorityLevelIndex) public view returns (DataTypes.SeniorityLevelInfo memory);
```

### getSeniorityLevels

Returns the seniority levels of the capital stack in ascending order as an array of 'DataTypes.SenioritylevelInfo' structs. For instance, the ith index of the return values would be considered below the ith + 1 index of the return values in the capital stack.

*Seniority level indexes are non-sequential*

```solidity
function getSeniorityLevels() public view virtual returns (DataTypes.SeniorityLevelInfo[] memory);
```

### getAssetsInSeniorityLevel

Returns the assets in the seniority level with 'seniorityLevelIndex' as an array of addresses

*Returns an empty array of addresses if 'seniorityLevelIndex' does not exist*

```solidity
function getAssetsInSeniorityLevel(uint256 seniorityLevelIndex) public view returns (address[] memory);
```

### getSeniorityLevelIndexByAsset

Returns zero if the asset is not in the stack. Otherwise, returns the seniority level index for 'asset'

```solidity
function getSeniorityLevelIndexByAsset(address asset) public view returns (uint256);
```

### getNumberOfAssetsInSeniorityLevel

Returns the number of assets in the seniority level with 'seniorityLevelIndex'

*Will also returns zero if the seniority level does not exist*

```solidity
function getNumberOfAssetsInSeniorityLevel(uint256 seniorityLevelIndex) public view returns (uint256);
```

### isAssetInCapitalStack

Returns true if 'asset' is in the capital stack, false otherwise

```solidity
function isAssetInCapitalStack(address asset) public view returns (bool);
```

### totalSeniorityLevels

Returns the total number of seniority levels

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

### getDocumentIndexByAsset

Returns the document index for 'asset'

*Reverts if 'asset' is not in the stack*

```solidity
function getDocumentIndexByAsset(address asset) public view returns (uint256);
```

### \_validateAssetIsInStack

*Reverts if 'asset' has not been added to the capital stack*

```solidity
function _validateAssetIsInStack(address asset) internal view virtual;
```

### \_addDocumentForAsset

*Creates a new document in the document registry, sets the '\_documentIndexByAsset' mapping, and returns the document index*

```solidity
function _addDocumentForAsset(address asset, string memory documentName, string memory documentUri)
    internal
    virtual
    returns (uint256);
```

### \_incrementCurrentSeniorityLevelIndex

*This function is kept as virtual in case overflow protection is desired in the future*

```solidity
function _incrementCurrentSeniorityLevelIndex() internal virtual returns (uint256);
```

### \_incrementSeniorityLevelsRemoved

*This function is kept as virtual in case overflow protection is desired in the future*

```solidity
function _incrementSeniorityLevelsRemoved() internal virtual;
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(MezzUUPSUpgradeable, IERC165)
    returns (bool);
```

### upgradeToNewerVersion

Upgrades 'this' to a newer version via the Mezz Migrator. Only callable by the Treasury, whose signers are the board of directors

*Will revert if the protocol state is 'Paused' or 'Frozen'*

```solidity
function upgradeToNewerVersion(uint256 newVersion, bytes memory data) public virtual onlyProxy onlyBoard;
```

**Parameters**

| Name         | Type      | Description                                                                                              |
| ------------ | --------- | -------------------------------------------------------------------------------------------------------- |
| `newVersion` | `uint256` | The new version to upgrade to                                                                            |
| `data`       | `bytes`   | The data to be passed to the new implementation, which likely should be a reinitializer function if used |

### \_authorizePatch

*Access control for 'resetToPatchedLatestVersion()'*

```solidity
function _authorizePatch(bytes memory) internal view virtual override;
```

## Structs

### CapitalStackStorage

```solidity
struct CapitalStackStorage {
    uint256 _currentSeniorityLevelIndex;
    uint256 _seniorityLevelsRemoved;
    mapping(uint256 => DataTypes.SeniorityLevel) _seniorityLevels;
    mapping(address => uint256) _seniorityLevelIndexByAsset;
    mapping(address => uint256) _documentIndexByAsset;
}
```


# DelegateRegistry

[Git Source](https://github.com/EntreDevelopers-Lab-Inc/Mezz-Companies/blob/f7a3e84e3dd5bb33c4bd7f77283983f9e8ba20b2/src/core/ancillary/delegate-registry/DelegateRegistry.sol)

**Inherits:** NoncesUpgradeable, StateAware, BoardControlled, Patchable, MezzEIP712, IDelegateRegistry

**Author:** Daniel Yamagata

A contract used to delegate voting power of a company's non-vesting and vesting shares. Delegates will receive the voting power of the delegator which can subsequently be used in governance

Invariant: the delegate of address(0) will always be address(0)

## State Variables

### DELEGATION\_TYPEHASH

```solidity
bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
```

### DelegateRegistryStorageLocation

```solidity
bytes32 private constant DelegateRegistryStorageLocation =
    0xa90ac951d12c63c63be62b72ff9c8457724b4d380ebdd06ffdd610ee98f70300;
```

## Functions

### constructor

```solidity
constructor(address _mezzHub, address _mezzMigrator) StateAware(_mezzHub) Patchable(_mezzMigrator);
```

### \_getDelegateRegistryStorage

```solidity
function _getDelegateRegistryStorage() internal pure returns (DelegateRegistryStorage storage $);
```

### init

Initializes the delegate registry's state. Called atomically by the Mezz Deployer

```solidity
function init(address initTreasury) external virtual initializer;
```

### \_\_DelegateRegisitry\_init

```solidity
function __DelegateRegisitry_init(address initTreasury) internal virtual onlyInitializing;
```

### selfDelegate

Self-delegates 'account' under the following conditions:

* account is not address(0)
* The delegatee of 'account' is not set
* The caller is a valid share class or the token timelock
* 'account' is an EOA or properly supports the 'IMezzSelfDelegator' interface&#x20;

If any of these conditions are false, the function will make no changes to state and return

```solidity
function selfDelegate(address account) external virtual;
```

### delegate

Updates the delegatee of the caller to 'newDelegatee' and updates the state of all share classes and the token timelock

```solidity
function delegate(address newDelegate) external virtual freezable;
```

### delegateBySig

Updates the delegatee of 'account' to 'newDelegatee' and updates the state of all share classes and the token timelock. A valid 'signature' for 'account' is required, otherwise this function will revert

```solidity
function delegateBySig(address account, address newDelegate, bytes memory signature) external virtual freezable;
```

### \_delegate

Validate

*Updates the voting power of 'newDelegate' for all shares and the Token Timelock. Runs in O(n) The number of shares that a company can have is limited to 15. This is reasonable, preventing the reversion of this function due to the block gas limit*

```solidity
function _delegate(address account, address newDelegate) internal virtual;
```

### delegates

Returns the delegatee for 'account' if it is set. Otherwise, returns address(0)

```solidity
function delegates(address account) public view virtual returns (address);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### getDelegationTransactionHash

Returns the transaction hash for

```solidity
function getDelegationTransactionHash(address account, address newDelegate, uint256 accountNonce)
    public
    view
    returns (bytes32);
```

### \_getDelegationStructHash

```solidity
function _getDelegationStructHash(address account, address newDelegate, uint256 accountNonce)
    internal
    pure
    returns (bytes32);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(MezzEIP712, MezzUUPSUpgradeable, IERC165)
    returns (bool);
```

### upgradeToNewerVersion

Upgrades 'this' to a newer version via the Mezz Migrator. Only callable by the Treasury, whose signers are the board of directors

*Will revert if the protocol state is 'Paused' or 'Frozen'*

```solidity
function upgradeToNewerVersion(uint256 newVersion, bytes memory data) public virtual onlyProxy onlyBoard;
```

**Parameters**

| Name         | Type      | Description                                                                                              |
| ------------ | --------- | -------------------------------------------------------------------------------------------------------- |
| `newVersion` | `uint256` | The new version to upgrade to                                                                            |
| `data`       | `bytes`   | The data to be passed to the new implementation, which likely should be a reinitializer function if used |

### \_authorizePatch

*Access control for 'resetToPatchedLatestVersion()'*

```solidity
function _authorizePatch(bytes memory) internal view virtual override;
```

## Structs

### DelegateRegistryStorage

```solidity
struct DelegateRegistryStorage {
    mapping(address => address) _delegateeByAccount;
}
```


# TokenTimelock

[Git Source](https://github.com/EntreDevelopers-Lab-Inc/Mezz-Companies/blob/f7a3e84e3dd5bb33c4bd7f77283983f9e8ba20b2/src/core/ancillary/token-timelock/TokenTimelock.sol)

**Inherits:** Patchable, StateAware, VotesDelegator, AdminControlled, MezzERC721Upgradeable, ITokenTimelock

**Author:** Daniel Yamagata & Naveen Ailawadi

This contract is used to vest a company's shares for a period of time. It is used by a company's Common Shares and Preferred Shares. The voting power of vesting shares can be delegated and used in governance

\*Invariants:

* \_erc20Vesting\[token] is always greater than or equal to \_erc20Released\[token]
* \_vestingScheduleByTokenId\[tokenId].amount is always greater than or equal to \_erc20ReleasedByTokenId\[tokenId]\[shares]. This is inclusive of when the token's data is deleted upon vesting completion or when the vesting is canceled\*

## State Variables

### TokenTimelockStorageLocation

```solidity
bytes32 private constant TokenTimelockStorageLocation =
    0x35f985dfceb352faec794b4221331a49707dbeacf0ce328e288c0a3b67d6cb00;
```

## Functions

### \_getTokenTimelockStorage

```solidity
function _getTokenTimelockStorage() internal pure returns (TokenTimelockStorage storage $);
```

### constructor

```solidity
constructor(address _mezzHub, address _mezzMigrator) StateAware(_mezzHub) Patchable(_mezzMigrator);
```

### receive

*The Token Timelock should not receive the native token used to pay for gas All native tokens transferred to this contract will be locked forever and effectively burned*

```solidity
receive() external payable;
```

### init

Initializes the token timelock contract

```solidity
function init(address initTreasury) external virtual initializer;
```

**Parameters**

| Name           | Type      | Description                          |
| -------------- | --------- | ------------------------------------ |
| `initTreasury` | `address` | The address of the treasury contract |

### \_\_TokenTimelock\_Init

```solidity
function __TokenTimelock_Init(address initTreasury) internal virtual onlyInitializing;
```

### treasury

Returns the address of the treasury, whose signers are the company's board of directors

```solidity
function treasury() public view override(BoardControlled, VotesDelegator, IBoardControlled) returns (ITreasury);
```

### vestShares

Vest shares for a recipient according to a vesting schedule. Vesting is cancellable by the board or a set of admins determined by the board depending on if it is obligatory

*'data.shares' must be tracked by the treasury, otherwise the function call will revert. This function uses an ERC721 safe transfer, which is susceptible to reentrancy. It follows the CEI pattern accordingly. There is no validation of 'data.startDate' being in the past. It is the responsibility of the caller to ensure its validity. If the start date is in the past farther than 'data.duration', the shares will be instantly vested. The max start date is two years into the future, at which point the shares will begin to vest*

```solidity
function vestShares(DataTypes.VestingData calldata data) external virtual returns (uint256);
```

**Parameters**

| Name   | Type                    | Description                                        |
| ------ | ----------------------- | -------------------------------------------------- |
| `data` | `DataTypes.VestingData` | The vesting data as a DataTypes.VestingData struct |

**Returns**

| Name     | Type      | Description                         |
| -------- | --------- | ----------------------------------- |
| `<none>` | `uint256` | The token ID for the vesting shares |

### release

Releases vested tokens to the owner of an ERC721. Can be called by anyone

*This function is not access controlled. Any account can release vested shares for any token ID Vested shares are transferred to the owner of the token*

```solidity
function release(uint256 tokenId) external virtual onlyTokenOwner(tokenId) returns (uint256);
```

**Parameters**

| Name      | Type      | Description                                      |
| --------- | --------- | ------------------------------------------------ |
| `tokenId` | `uint256` | The ID of the token to release vested shares for |

**Returns**

| Name     | Type      | Description                             |
| -------- | --------- | --------------------------------------- |
| `<none>` | `uint256` | The amount of shares that were released |

### cancelVestingAtTimepoint

Cache and Validate

*This function is primarily used by the Payroll Manager when an employee resigns at a timepoint*

```solidity
function cancelVestingAtTimepoint(uint256 tokenId, uint256 timepoint) external virtual returns (uint256);
```

**Returns**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `<none>` | `uint256` | The amount of canceled shares |

### cancelVesting

Cancels the vesting for a given token. Releases any vested shares and burns the remaining amount allocated to the token.

*This function will revert if the caller is not the token owner nor an admin. If the caller is an admin, this function will revert if the token is obligatory*

```solidity
function cancelVesting(uint256 tokenId) external virtual returns (uint256, uint256);
```

**Parameters**

| Name      | Type      | Description                                   |
| --------- | --------- | --------------------------------------------- |
| `tokenId` | `uint256` | The ID of the token to cancel the vesting for |

**Returns**

| Name     | Type      | Description                                                                                                                                    |
| -------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `uint256` | Returns two arguments. The first is the amount of shares that were released. The second is the amount of shares that were cancelled and burned |
| `<none>` | `uint256` |                                                                                                                                                |

### \_cancelVesting

```solidity
function _cancelVesting(uint256 tokenId) internal virtual returns (uint256, uint256);
```

### \_handleCanceledShares

*If the owner is the payroll manager, transfer the vesting shares back to the treasury Otherwise, burn the shares. This is done to prevent the treasury from having to re-authorize and re-issue shares that were allocated to employees but subsequently canceled*

```solidity
function _handleCanceledShares(uint256 tokenId, address shares, uint256 amountCanceled) internal;
```

### extendVestingDuration

Extends the vesting duration for the given 'tokenId'. Only callable by the token owner

*This function will revert if the token does not exist*

```solidity
function extendVestingDuration(uint256 tokenId, uint256 durationExtension)
    external
    virtual
    onlyTokenOwner(tokenId)
    returns (uint32);
```

**Parameters**

| Name                | Type      | Description                                            |
| ------------------- | --------- | ------------------------------------------------------ |
| `tokenId`           | `uint256` | The ID of the token to extend the vesting duration for |
| `durationExtension` | `uint256` | The amount of time to extend the vesting duration by   |

**Returns**

| Name     | Type     | Description              |
| -------- | -------- | ------------------------ |
| `<none>` | `uint32` | The new vesting duration |

### extendVestingAmount

Increases the vesting amount for 'tokenId' by 'equityExtension'

*This function is not access controlled. It is callable by anyone This function will revert if the token does not exist*

```solidity
function extendVestingAmount(uint256 tokenId, uint256 equityExtension) external virtual returns (uint256);
```

**Parameters**

| Name              | Type      | Description                                            |
| ----------------- | --------- | ------------------------------------------------------ |
| `tokenId`         | `uint256` | The ID of the token to increase the vesting amount for |
| `equityExtension` | `uint256` | The amount to increase the vesting amount by           |

**Returns**

| Name     | Type      | Description            |
| -------- | --------- | ---------------------- |
| `<none>` | `uint256` | The new vesting amount |

### updateDelegate

Updates the delegate of 'delegator' from 'fromDelegate' to 'toDelegate'. Only callable by the Delegate Registry

```solidity
function updateDelegate(address delegator, address fromDelegate, address toDelegate)
    external
    virtual
    override(VotesDelegator, IVotesDelegator)
    onlyDelegateRegistry;
```

### isObligatory

Returns whether or not a given token is obligatory

```solidity
function isObligatory(uint256 tokenId) public view returns (bool);
```

**Parameters**

| Name      | Type      | Description         |
| --------- | --------- | ------------------- |
| `tokenId` | `uint256` | The ID of the token |

**Returns**

| Name     | Type   | Description                            |
| -------- | ------ | -------------------------------------- |
| `<none>` | `bool` | Whether or not the token is obligatory |

### wasCanceled

Returns true if the token was canceled, false otherwise

```solidity
function wasCanceled(uint256 tokenId) public view returns (bool);
```

### hasCompleted

Returns true if the token has completed its vesting, false otherwise

```solidity
function hasCompleted(uint256 tokenId) public view returns (bool);
```

### exists

Returns true if the token exists, false otherwise

```solidity
function exists(uint256 tokenId) public view returns (bool);
```

### getVestingSchedule

Returns the vesting schedule for the given token

```solidity
function getVestingSchedule(uint256 tokenId) public view returns (DataTypes.VestingSchedule memory);
```

**Parameters**

| Name      | Type      | Description         |
| --------- | --------- | ------------------- |
| `tokenId` | `uint256` | The ID of the token |

**Returns**

| Name     | Type                        | Description                                                |
| -------- | --------------------------- | ---------------------------------------------------------- |
| `<none>` | `DataTypes.VestingSchedule` | The vesting schedule as a DataTypes.VestingSchedule struct |

### getRemainingVestingAmount

Returns the remaining vesting amount for the given token

*The remaining vesting amount refers to the difference between the shares attributed to the vesting schedule and how much has been released*

```solidity
function getRemainingVestingAmount(uint256 tokenId) public view returns (uint256);
```

### getVestingEndDate

Returns the Unix-timestamp in seconds at which the vesting schedule will complete

```solidity
function getVestingEndDate(uint256 tokenId) public view returns (uint256);
```

### released

Returns the amount of shares that have been released for a given token

```solidity
function released(uint256 tokenId) public view returns (uint256);
```

**Parameters**

| Name      | Type      | Description         |
| --------- | --------- | ------------------- |
| `tokenId` | `uint256` | The ID of the token |

**Returns**

| Name     | Type      | Description                                                |
| -------- | --------- | ---------------------------------------------------------- |
| `<none>` | `uint256` | The amount of shares that have been released for the token |

### releasable

Returns the amount of shares that are releasable for a given token. 'Releasable' refers to the amount of shares that have vested and have not yet been released

```solidity
function releasable(uint256 tokenId) public view returns (uint256);
```

**Parameters**

| Name      | Type      | Description         |
| --------- | --------- | ------------------- |
| `tokenId` | `uint256` | The ID of the token |

**Returns**

| Name     | Type      | Description                                            |
| -------- | --------- | ------------------------------------------------------ |
| `<none>` | `uint256` | The amount of shares that are releasable for the token |

### getVotesByShareClass

Returns the current number of voting units for 'account' based on 'shares'

*The return value does not adjust for the voting weight of 'shares'*

```solidity
function getVotesByShareClass(address account, address shares) public view virtual returns (uint256);
```

### getPastVotesByShareClass

Returns the voting units for 'account' based on 'shares' at the given 'timepoint'

*The return value does not adjust for the voting weight of 'shares'. This function will revert if 'timepoint' is in the present or the future*

```solidity
function getPastVotesByShareClass(address account, address shares, uint256 timepoint)
    public
    view
    virtual
    returns (uint256);
```

### getERC20VestingByAccount

Returns the current amount of 'shares' that are vesting for 'account'

```solidity
function getERC20VestingByAccount(address account, address shares) public view returns (uint256);
```

### getCumulativeERC20Vesting

Returns the cumlative amount of shares that are vesting or *have been* vested in the token timelock

```solidity
function getCumulativeERC20Vesting(address shares) public view returns (uint256);
```

**Parameters**

| Name     | Type      | Description                        |
| -------- | --------- | ---------------------------------- |
| `shares` | `address` | The address of the shares contract |

**Returns**

| Name     | Type      | Description                                                                       |
| -------- | --------- | --------------------------------------------------------------------------------- |
| `<none>` | `uint256` | The amount of shares that are vesting or *have been* vested in the token timelock |

### getCumulativeERC20Released

Returns the cumlative amount of shares that have been released from the token timelock

```solidity
function getCumulativeERC20Released(address shares) public view returns (uint256);
```

**Parameters**

| Name     | Type      | Description                        |
| -------- | --------- | ---------------------------------- |
| `shares` | `address` | The address of the shares contract |

**Returns**

| Name     | Type      | Description                                                          |
| -------- | --------- | -------------------------------------------------------------------- |
| `<none>` | `uint256` | The amount of shares that have been released from the token timelock |

### name

Returns the name of the token timelock

```solidity
function name() public view virtual override(ERC721Upgradeable, ITokenTimelock) returns (string memory);
```

### symbol

Returns the symbol of the token timelock

```solidity
function symbol() public view virtual override(ERC721Upgradeable, ITokenTimelock) returns (string memory);
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```

### \_release

*Releases the '\_releasableAmount' of vested shares to the owner of the token 'Releasable' refers to the amount vested minus the amount already released*

```solidity
function _release(uint256 tokenId, address shares, uint256 _releasableAmount) internal;
```

**Parameters**

| Name                | Type      | Description                                                                         |
| ------------------- | --------- | ----------------------------------------------------------------------------------- |
| `tokenId`           | `uint256` | The token ID to release tokens for                                                  |
| `shares`            | `address` | The address of the shares that are being released and correspond to the given token |
| `_releasableAmount` | `uint256` | The amount of tokens that are releasable                                            |

### \_releasable

*Returns the amount of tokens that are 'releasable' for a given token 'Releasable' refers to the amount vested minus the amount already released*

```solidity
function _releasable(uint256 tokenId) internal view virtual returns (uint256);
```

**Parameters**

| Name      | Type      | Description  |
| --------- | --------- | ------------ |
| `tokenId` | `uint256` | The token ID |

**Returns**

| Name     | Type      | Description                              |
| -------- | --------- | ---------------------------------------- |
| `<none>` | `uint256` | The amount of tokens that are releasable |

### \_vestedAmount

*Calculates the vested amount of shares for a given vesting schedule. Does not check the released amount of shares Precision loss is possible, but extremely unlikely since shares will always have 18 decimals*

```solidity
function _vestedAmount(DataTypes.VestingSchedule memory vestingScheduleCache) internal view virtual returns (uint256);
```

**Parameters**

| Name                   | Type                        | Description                                             |
| ---------------------- | --------------------------- | ------------------------------------------------------- |
| `vestingScheduleCache` | `DataTypes.VestingSchedule` | The vesting schedule to calculate the vested amount for |

**Returns**

| Name     | Type      | Description                 |
| -------- | --------- | --------------------------- |
| `<none>` | `uint256` | The vested amount of shares |

### \_burnTokenAndDeleteData

*Burn a token with 'tokenId' and deletes it corresponding data in storage*

```solidity
function _burnTokenAndDeleteData(uint256 tokenId, address _shares) internal;
```

**Parameters**

| Name      | Type      | Description                                                  |
| --------- | --------- | ------------------------------------------------------------ |
| `tokenId` | `uint256` | The ID of the token to burn                                  |
| `_shares` | `address` | The address of the shares that correspond to the given token |

### \_validateCallerIsOwnerOrAdminAndNonObligatory

\*Reverts if:

* The caller is not the token owner or an admin
* If the caller is an admin *and* the token is obligatory\*

```solidity
function _validateCallerIsOwnerOrAdminAndNonObligatory(uint256 tokenId) internal view virtual;
```

### \_checkInvariants

*Asserts that the invariants hold true. Panics otherwise*

```solidity
function _checkInvariants(uint256 tokenId) internal view virtual;
```

**Parameters**

| Name      | Type      | Description                              |
| --------- | --------- | ---------------------------------------- |
| `tokenId` | `uint256` | The token ID to check the invariants for |

### \_update

*Overridden updated from '\_ERC721Upgradeable' such that the voting units of a delegate is updated on token transfer, including burning*

```solidity
function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address);
```

**Returns**

| Name     | Type      | Description            |
| -------- | --------- | ---------------------- |
| `<none>` | `address` | The owner of 'tokenId' |

### \_transferVotingUnits

*Transfers the voting units of 'shares' from the delegatee of 'from' to the delegatee of 'to'*

```solidity
function _transferVotingUnits(address from, address to, address shares, uint256 amount) internal virtual;
```

### \_moveDelegateVotes

*Moves delegated votes of 'shares' from one delegate to another*

```solidity
function _moveDelegateVotes(address from, address to, address shares, uint256 amount) internal virtual;
```

### \_push

```solidity
function _push(Checkpoints.Trace208 storage store, function(uint208, uint208) view returns (uint208) op, uint208 delta)
    internal
    returns (uint208, uint208);
```

### \_add

```solidity
function _add(uint208 a, uint208 b) internal pure returns (uint208);
```

### \_subtract

```solidity
function _subtract(uint208 a, uint208 b) internal pure returns (uint208);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(ERC721Upgradeable, MezzUUPSUpgradeable, IERC165)
    returns (bool);
```

### upgradeToNewerVersion

Upgrades 'this' to a newer version via the Mezz Migrator. Only callable by the Treasury, whose signers are the board of directors

*Will revert if the protocol state is 'Paused' or 'Frozen'*

```solidity
function upgradeToNewerVersion(uint256 newVersion, bytes memory data) public virtual onlyProxy onlyBoard;
```

**Parameters**

| Name         | Type      | Description                                                                                              |
| ------------ | --------- | -------------------------------------------------------------------------------------------------------- |
| `newVersion` | `uint256` | The new version to upgrade to                                                                            |
| `data`       | `bytes`   | The data to be passed to the new implementation, which likely should be a reinitializer function if used |

### \_authorizePatch

*Access control for 'resetToPatchedLatestVersion()'*

```solidity
function _authorizePatch(bytes memory) internal view virtual override;
```

## Structs

### TokenTimelockStorage

```solidity
struct TokenTimelockStorage {
    mapping(address => uint256) _erc20Vesting;
    mapping(address => uint256) _erc20Released;
    mapping(uint256 => DataTypes.VestingSchedule) _vestingScheduleByTokenId;
    mapping(uint256 tokenId => mapping(address erc20 => uint256)) _erc20ReleasedByTokenId;
    mapping(address account => mapping(address erc20 => uint256)) _erc20VestingByAccount;
    mapping(address delegatee => mapping(address shares => Checkpoints.Trace208)) _delegateCheckpointsByShares;
}
```


# PayrollManager

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

**Inherits:** NoncesUpgradeable, ReentrancyGuardUpgradeable, Patchable, StateAware, AdminControlled, MezzEIP712, MezzERC721Upgradeable, IPayrollManager

**Author:** Daniel Yamagata

A soulbound ERC721 contract that manages the payroll of a company. The contract is controlled by the company's board of directors and a set of admins set by the board. Some actions require a 24-hour time delay before they are executable. This was done such that a compromised admin cannot drain a company's funds instantaneously. Rather, the action can be canceled by the board or another admin before its execution. These actions include:

* Changing an employee's cash salary
* Extending an employee's equity payments
* Setting a new equity payment schedule for an employee
* Paying cash directly to an employee
* Paying equity directly to an employee

*The tokens are never burned, even after an employee resigns or is terminated. This was done such to preserve the on-chain data that an employee once worked at a company. Whether or not an employee resigned or was terminated is tracked accordingly.*

## State Variables

### HIRE\_TYPEHASH

```solidity
bytes32 public constant HIRE_TYPEHASH = keccak256(
    "Hire(address employee,uint256 annualCash,uint256 equityAmount,uint48 startDate,uint32 vestingDuration,uint32 vestingCliff,uint256 vestingInitialUnlock,uint256 employeeNonce)"
);
```

### RESIGN\_TYPEHASH

```solidity
bytes32 public constant RESIGN_TYPEHASH = keccak256("Resign(uint256 tokenId,uint256 endDate,uint256 employeeNonce)");
```

### EQUITY\_EXTENSION\_TYPEHASH

```solidity
bytes32 public constant EQUITY_EXTENSION_TYPEHASH = keccak256(
    "EquityExtension(uint256 tokenId,uint256 equityAmount,uint256 vestingDurationIncrease,uint256 employeeNonce)"
);
```

### PayrollManagerStorageLocation

```solidity
bytes32 private constant PayrollManagerStorageLocation =
    0xf4d0e5fd25e5b6673737e0c7092828613247d816b3e8d4d3ee07c337421a2e00;
```

## Functions

### \_getPayrollManagerStorage

```solidity
function _getPayrollManagerStorage() internal pure returns (PayrollManagerStorage storage $);
```

### requireEmployed

*Reverts if the token ID does not correspond to a current employee*

```solidity
modifier requireEmployed(uint256 tokenId);
```

### constructor

```solidity
constructor(address _mezzHub, address _mezzMigrator) StateAware(_mezzHub) Patchable(_mezzMigrator);
```

### init

Initializes the Payroll Manager. The 'initTreasury' is set as the controller of the contract. Can only be called once.

*The payroll manager is initialized upon a company's deployment within the Mezz Deployer*

```solidity
function init(address initTreasury) external virtual initializer;
```

**Parameters**

| Name           | Type      | Description                                        |
| -------------- | --------- | -------------------------------------------------- |
| `initTreasury` | `address` | The treasury that will control the payroll manager |

### \_\_PayrollManager\_init

```solidity
function __PayrollManager_init(address initTreasury) internal virtual onlyInitializing;
```

### hire

Hires an employee with an annual salary and equity. An employee's start date must be at least 24 hours after calling this function. Only callable by 'admins' or the board of directors, who are the signers of the treasury

*An employee signature must be included such that they accept their offer. This prevents companies from defrauding others by claiming that they have hired a certain employee. It also confirms that the employee has accepted the terms of the agreement, so that they do not have to be altered at a later time*

```solidity
function hire(DataTypes.HireData memory data, bytes memory employeeSignature)
    external
    virtual
    onlyAdmin
    nonReentrant
    pausable
    returns (uint256);
```

**Parameters**

| Name                | Type                 | Description                                                                                                                    |
| ------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `data`              | `DataTypes.HireData` | The data needed to hire an employee, defined as DataTypes.HireData                                                             |
| `employeeSignature` | `bytes`              | The signature of the employee. The employee should sign the hash of 'getHireTransactionHash' with the terms of their agreement |

**Returns**

| Name     | Type      | Description                 |
| -------- | --------- | --------------------------- |
| `<none>` | `uint256` | The ID of the payroll token |

### terminate

```solidity
function terminate(uint256[] memory tokenIds) external virtual onlyAdmin freezable;
```

### terminate

Terminates the employees associated with 'tokenId'. Collects all collectible cash for 'tokenId'.  Only callable by an admin

```solidity
function terminate(uint256 tokenId) public virtual onlyAdmin freezable;
```

### increaseUnpaidTimeOff

```solidity
function increaseUnpaidTimeOff(uint256[] memory tokenIds, uint48[] memory timeOff)
    external
    virtual
    onlyAdmin
    freezable;
```

### increaseUnpaidTimeOff

Increases the unpaid time off for the employees associated with 'tokenId' by 'timeOff'. Only callable by an admin. Collects any collectible cash associated with 'tokenIds'

```solidity
function increaseUnpaidTimeOff(uint256 tokenId, uint48 timeOff) external virtual onlyAdmin freezable;
```

### collectCash

Collects the cash owed to an employee. If the treasury does not have a sufficcient cash balance, the cash owed to an employee is updated, such that it will be collectible at a later time. The cash is transferred to the employee's specified recipient, which may be different from the employee, themself.

*This function is not access controlled. Any account can collect cash on behalf of an employee.*

```solidity
function collectCash(uint256 tokenId) public virtual pausable returns (uint256);
```

**Parameters**

| Name      | Type      | Description                 |
| --------- | --------- | --------------------------- |
| `tokenId` | `uint256` | The ID of the payroll token |

**Returns**

| Name     | Type      | Description                                                                                                                                                          |
| -------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `uint256` | The amount of cash paid, which may be different than the amount that was collectible. This is due to potential transfer fees that may be incurred by the cash asset. |

### collectEquity

Collects the equity owed to an employee. The common shares are transferred to the employee's specified recipient. Equity compensation will always be in the form of the company's common shares. This function is callable by any account

*This function is not access controlled. Any account can collect cash on behalf of an employee. This function is will revert if the employee's vesting schedule has been completed or if they did not have a vesting schedule to begin with.*

```solidity
function collectEquity(uint256 tokenId) public virtual pausable returns (uint256);
```

**Parameters**

| Name      | Type      | Description                 |
| --------- | --------- | --------------------------- |
| `tokenId` | `uint256` | The ID of the payroll token |

**Returns**

| Name     | Type      | Description                   |
| -------- | --------- | ----------------------------- |
| `<none>` | `uint256` | The amount of equity released |

### changeRecipient

Changes the recipient of the employee's salary to 'newRecipient'. Only callable by the owner of 'tokenId'

```solidity
function changeRecipient(uint256 tokenId, address newRecipient) external virtual onlyTokenOwner(tokenId) pausable;
```

### resign

Resigns the employee associated with 'tokenId'. Only callable by the token owner. The employee will continue to earn their salary until their 'salaryEndDate'

*The 'salaryEndDate' cannot exceed 1 year into the future and cannot be in the past*

```solidity
function resign(uint256 tokenId, uint256 salaryEndDate) external onlyTokenOwner(tokenId) freezable;
```

**Parameters**

| Name            | Type      | Description                                               |
| --------------- | --------- | --------------------------------------------------------- |
| `tokenId`       | `uint256` | The ID of the payroll token                               |
| `salaryEndDate` | `uint256` | The date that the employee will stop earning their salary |

### resignBySig

Resigns the employee associated with 'tokenId'. A signature from the employee is required. The employee will continue to earn their salary until their 'salaryEndDate'

```solidity
function resignBySig(uint256 tokenId, uint256 salaryEndDate, bytes memory employeeSignature) external freezable;
```

**Parameters**

| Name                | Type      | Description                                                                                    |
| ------------------- | --------- | ---------------------------------------------------------------------------------------------- |
| `tokenId`           | `uint256` | The ID of the payroll token                                                                    |
| `salaryEndDate`     | `uint256` | The date that the employee will stop earning their salary                                      |
| `employeeSignature` | `bytes`   | The signature of the employee. The employee should sign the hash of 'getResignTransactionHash' |

### \_resign

```solidity
function _resign(uint256 tokenId, uint256 salaryEndDate) internal virtual;
```

### proposeActions

Proposes a series of 'actions' to be executed in the future. Each action has a corresponding 'params' which are the abi-encoded arguments of the actions' corresponding function. Only callable by an admin.

```solidity
function proposeActions(bytes4[] memory actions, bytes[] memory params)
    public
    virtual
    onlyAdmin
    pausable
    returns (bytes32[] memory);
```

**Parameters**

| Name      | Type       | Description                                                      |
| --------- | ---------- | ---------------------------------------------------------------- |
| `actions` | `bytes4[]` | The actions to be executed                                       |
| `params`  | `bytes[]`  | The abi-encoded arguments of the actions' corresponding function |

### proposeAction

Proposed actions require a minimum delay of 24 hours before their execution. This is done such that a compromised admin cannot drain the company's funds instantaneously. Rather, the action can be canceled by another admin within the 24-hour window. Once the delay has passed, any account can execute the action. Actions that include a delay are:

* Changing an employee's cash salary
* Extending an employee's equity payments
* Setting a new equity payment schedule for an employee
* Paying cash directly to an employee
* Paying equity directly to an employee This function will revert if the action has already been proposed.

```solidity
function proposeAction(bytes4 action, bytes memory params) public virtual onlyAdmin pausable returns (bytes32);
```

**Parameters**

| Name     | Type     | Description                                                            |
| -------- | -------- | ---------------------------------------------------------------------- |
| `action` | `bytes4` | The action to be executed, represented as the selector of the function |
| `params` | `bytes`  | The abi-encoded parameters of the action.                              |

**Returns**

| Name     | Type      | Description                                                              |
| -------- | --------- | ------------------------------------------------------------------------ |
| `<none>` | `bytes32` | The ID of the action, which is the hash of the action and its parameters |

### cancelPendingAction

Cancels a pending action. Only callable by an admin

```solidity
function cancelPendingAction(bytes32 actionId) external;
```

**Parameters**

| Name       | Type      | Description                         |
| ---------- | --------- | ----------------------------------- |
| `actionId` | `bytes32` | The ID of the action to be canceled |

### changeCashSalary

Changes the cash salary of the employee with 'tokenId' to 'newCashSalary'

```solidity
function changeCashSalary(uint256 tokenId, uint256 newCashSalary) external virtual requireEmployed(tokenId) pausable;
```

**Parameters**

| Name            | Type      | Description                                |
| --------------- | --------- | ------------------------------------------ |
| `tokenId`       | `uint256` | The ID of the payroll token                |
| `newCashSalary` | `uint256` | The new annual cash salary of the employee |

### extendEquityPayments

Extends the equity payments of 'tokenId' by 'equityExtension' and increases the duration by 'durationExtension'

*Must be proposed by an admin and executed after a 24 hour delay This function will revert if the vesting schedule associated with 'tokenId' is non-existent, which can occur if the employee never had a vesting schedule to begin with or their vesting schedule has been completed*

```solidity
function extendEquityPayments(
    uint256 tokenId,
    uint256 equityExtension,
    uint32 durationExtension,
    bytes memory employeeSignature
) external virtual requireEmployed(tokenId) pausable;
```

**Parameters**

| Name                | Type      | Description                                                                                                                                                                                                                                                          |
| ------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tokenId`           | `uint256` | The ID of the payroll token                                                                                                                                                                                                                                          |
| `equityExtension`   | `uint256` | The number of shares to be added to the employee's equity payments                                                                                                                                                                                                   |
| `durationExtension` | `uint32`  | The number of seconds to be added to the employee's vesting schedule                                                                                                                                                                                                 |
| `employeeSignature` | `bytes`   | The signature of the employee. The employee should sign the hash of 'getEquityExtensionTransactionHash' The employee signature is needed such that an employer cannot arbitrarily increase the of an employee's vesting schedule without the consent of the employee |

### setNewEquityPayments

Sets a new equity payment schedule for 'tokenId'

*Must be proposed by an admin and executed after a 24 hour delay This function will revert if 'tokenId' has an existing vesting schedule*

```solidity
function setNewEquityPayments(uint256 tokenId, DataTypes.NewEquityPaymentsData memory data)
    external
    virtual
    requireEmployed(tokenId)
    nonReentrant
    pausable
    returns (uint256);
```

**Parameters**

<table><thead><tr><th>Name</th><th width="156">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>tokenId</code></td><td><code>uint256</code></td><td>The ID of the payroll token</td></tr><tr><td><code>data</code></td><td><code>DataTypes.NewEquityPaymentsData</code></td><td><p>The new equity payment data as a DataTypes.NewEquityPaymentsData struct </p><p>- data.equityAmount: The total number of shares to be paid to the employee </p><p>- data.startDate: The start date of the employee, represented as a unix timestamp </p><p>- data.vestingDuration: The number of seconds that it will take for the employee to be able to claim all of their shares </p><p>- data.vestingCliff: The number of seconds that it will take for the employee to be able to claim their first shares </p><p>- data.vestingInitialUnlock: The number of shares that the employee will be able to claim at the end of their cliff</p></td></tr></tbody></table>

### payCash

Pays 'cashPaymentAmount' to the recipient of 'tokenId' in the cash asset of the employee, which should be the company's denomination asset. The recipient may be different from the employee, themself

*Must be proposed by an admin and executed after a 24 hour delay 'cashPaymentAmount' cannot exceed $10 million*

```solidity
function payCash(uint256 tokenId, uint256 cashPaymentAmount, bytes32 encodedDetails)
    external
    virtual
    requireEmployed(tokenId)
    pausable
    returns (uint256);
```

**Parameters**

<table><thead><tr><th>Name</th><th width="135">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>tokenId</code></td><td><code>uint256</code></td><td>The ID of the payroll token</td></tr><tr><td><code>cashPaymentAmount</code></td><td><code>uint256</code></td><td>The amount of cash to be paid to the employee</td></tr><tr><td><code>encodedDetails</code></td><td><code>bytes32</code></td><td>Details regarding the cash payment as a bit-field. Must be either encoded to include either or both: DataTypes.PaymentDetails.Bonus or DataTypes.PaymentDetails.ContractorPayment. 'Encoding' is done by shifting left 1 by the value of the Payment Details enum</td></tr></tbody></table>

**Returns**

| Name     | Type      | Description                                                                                     |
| -------- | --------- | ----------------------------------------------------------------------------------------------- |
| `<none>` | `uint256` | The amount paid, which may be different than the 'cashPaymentAmount' due to ERC20 transfer fees |

### payEquity

Pays 'equityPaymentAmount' to the recipient of 'tokenId' in the form of the company's common shares

*Must be proposed by an admin and executed after a 24 hour delay 'equityPaymentAmount' cannot exceed the treasury common shares*

```solidity
function payEquity(uint256 tokenId, uint256 equityPaymentAmount, bytes32 encodedDetails)
    external
    virtual
    requireEmployed(tokenId)
    pausable;
```

**Parameters**

| Name                  | Type      | Description                                                                                                                                                                                                                                                         |
| --------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tokenId`             | `uint256` | The ID of the payroll token                                                                                                                                                                                                                                         |
| `equityPaymentAmount` | `uint256` | The amount of equity to be paid to the employee                                                                                                                                                                                                                     |
| `encodedDetails`      | `bytes32` | Details regarding the equity payment as a bit-field. Must be either encoded to include either or both: DataTypes.PaymentDetails.Bonus or DataTypes.PaymentDetails.ContractorPayment. 'Encoding' is done by shifting left 1 by the value of the Payment Details enum |

### updateEmployeeDocument

Updates the document related to the employee with 'tokenId' in the Document Registry. Only callable by the board or an admin

```solidity
function updateEmployeeDocument(uint256 tokenId, string memory updatedDocumentName, string memory updatedDocumentUri)
    external
    virtual
    onlyAdmin
    returns (uint256);
```

**Returns**

| Name     | Type      | Description                     |
| -------- | --------- | ------------------------------- |
| `<none>` | `uint256` | The new version of the document |

### collectibleCash

Returns the amount of cash collectible by 'tokenId'

*This function will revert if 'tokenId' has not been minted*

```solidity
function collectibleCash(uint256 tokenId) public view virtual returns (uint256);
```

### collectibleEquity

Returns the amount of equity collectible by 'tokenId'

*This function will revert if 'tokenId' has not been minted*

```solidity
function collectibleEquity(uint256 tokenId) public view virtual returns (uint256);
```

### isEmployee

Returns true if 'tokenId' is a current employee, false otherwise

*This function will revert if 'tokenId' has not been minted. It will return false if the employee's end date has passed. An end date is set during an employee's termination or resignation*

```solidity
function isEmployee(uint256 tokenId) public view virtual returns (bool);
```

### getSalary

Returns the salary of 'tokenId' in the form of a DataTypes.Salary struct

*To query the vesting schedule of the employee, call 'getVestingSchedule()' of the company's token timelock with the salary's 'tokenTimelockTokenId'*

```solidity
function getSalary(uint256 tokenId) public view returns (DataTypes.Salary memory);
```

### hashAction

Returns the action id of an 'action' given its abi-encoded 'params'

```solidity
function hashAction(bytes4 action, bytes memory params) public pure virtual returns (bytes32);
```

### isActionReady

Returns true if the pending action associated with 'actionId' is ready to execute, false otherwise

*Will return false instead of reverting, even if the pending action does not exist*

```solidity
function isActionReady(bytes32 actionId) public view virtual returns (bool);
```

### isPendingAction

Returns true if the pending action associated with 'actionId' exists, false otherwise

```solidity
function isPendingAction(bytes32 actionId) public view returns (bool);
```

### getPendingActions

Returns the action IDs of all outstanding pending actions as a bytes32 array

```solidity
function getPendingActions() public view returns (bytes32[] memory);
```

### getPendingActionSnapshot

Returns the snapshot of the pending action associated with 'actionId' The snapshot is the unix timestamp at which the action can be executed

```solidity
function getPendingActionSnapshot(bytes32 actionId) public view returns (uint256);
```

### getHireTransactionHash

Returns the transaction hash of the encoded hire data

*This hash is to be signed by the employee before being hired*

```solidity
function getHireTransactionHash(
    address employee,
    uint256 annualCash,
    uint256 equityAmount,
    uint48 startDate,
    uint32 vestingDuration,
    uint32 vestingCliff,
    uint256 vestingInitialUnlock,
    uint256 employeeNonce
) public view returns (bytes32);
```

**Parameters**

| Name                   | Type      | Description                                                                                      |
| ---------------------- | --------- | ------------------------------------------------------------------------------------------------ |
| `employee`             | `address` | The employee to hire                                                                             |
| `annualCash`           | `uint256` | The annual cash salary of the employee                                                           |
| `equityAmount`         | `uint256` | The total number of shares to be paid to the employee over 'vestingDuration'                     |
| `startDate`            | `uint48`  | The start date of the employee, represented as a unix timestamp                                  |
| `vestingDuration`      | `uint32`  | The number of seconds that it will take for the employee to be able to claim all of their shares |
| `vestingCliff`         | `uint32`  | The number of seconds that it will take for the employee to be able to claim their first shares  |
| `vestingInitialUnlock` | `uint256` | The number of shares that the employee will be able to claim at the end of their cliff           |
| `employeeNonce`        | `uint256` | The nonce of the employee, which is used to prevent replay attacks                               |

### \_getHireStructHash

Encodes hire data as a struct hash following the EIP-712 encoding standards

*Reference: <https://eips.ethereum.org/EIPS/eip-712>*

```solidity
function _getHireStructHash(
    address employee,
    uint256 annualCash,
    uint256 equityAmount,
    uint48 startDate,
    uint32 vestingDuration,
    uint32 vestingCliff,
    uint256 vestingInitialUnlock,
    uint256 employeeNonce
) internal pure returns (bytes32);
```

### getResignTransactionHash

Returns the transaction hash of the encoded resign data

*This hash is to be signed by the employee when resigning via signature*

```solidity
function getResignTransactionHash(uint256 tokenId, uint256 endDate, uint256 employeeNonce)
    public
    view
    returns (bytes32);
```

**Parameters**

| Name            | Type      | Description                                                        |
| --------------- | --------- | ------------------------------------------------------------------ |
| `tokenId`       | `uint256` | The ID of the payroll token                                        |
| `endDate`       | `uint256` | The date that the employee will stop earning their salary          |
| `employeeNonce` | `uint256` | The nonce of the employee, which is used to prevent replay attacks |

### \_getResignStructHash

Encodes resign data as a struct hash following the EIP-712 encoding standards

*Reference: <https://eips.ethereum.org/EIPS/eip-712>*

```solidity
function _getResignStructHash(uint256 tokenId, uint256 endDate, uint256 employeeNonce)
    internal
    pure
    returns (bytes32);
```

### getEquityExtensionTransactionHash

Returns the transaction hash of the encoded equity extension data

*This hash is to be signed by the employee when extending their equity payments*

```solidity
function getEquityExtensionTransactionHash(
    uint256 tokenId,
    uint256 equityExtension,
    uint32 durationExtension,
    uint256 employeeNonce
) public view returns (bytes32);
```

**Parameters**

| Name                | Type      | Description                                                                  |
| ------------------- | --------- | ---------------------------------------------------------------------------- |
| `tokenId`           | `uint256` | The ID of the payroll token                                                  |
| `equityExtension`   | `uint256` | The total number of shares to be paid to the employee over 'vestingDuration' |
| `durationExtension` | `uint32`  | The number of seconds to be added to the employee's vesting schedule         |
| `employeeNonce`     | `uint256` | The nonce of the employee, which is used to prevent replay attacks           |

### \_getEquityExtensionStructHash

Encodes equity extension data as a struct hash following the EIP-712 encoding standards

*Reference: <https://eips.ethereum.org/EIPS/eip-712>*

```solidity
function _getEquityExtensionStructHash(
    uint256 tokenId,
    uint256 equityExtension,
    uint32 durationExtension,
    uint256 employeeNonce
) internal pure returns (bytes32);
```

### name

Returns the name of the Payroll Manager

```solidity
function name() public view virtual override(ERC721Upgradeable, IPayrollManager) returns (string memory);
```

### symbol

Returns the symbol of the Payroll Manager

```solidity
function symbol() public view virtual override(ERC721Upgradeable, IPayrollManager) returns (string memory);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### \_validateSignature

```solidity
function _validateSignature(address signer, bytes32 txHash, bytes memory signature) internal view;
```

### \_validateAreEmployees

```solidity
function _validateAreEmployees(uint256[] memory tokenIds) internal view virtual;
```

### \_validateIsEmployee

```solidity
function _validateIsEmployee(uint256 tokenId) internal view virtual;
```

### \_getAddressesForEmployees

*Returns the addresses of employees for a given set of token IDs*

```solidity
function _getAddressesForEmployees(uint256[] memory tokenIds) internal view returns (address[] memory);
```

### \_getCollectibleCashForEmployees

*Returns the collectible cash for a given set of token IDs*

```solidity
function _getCollectibleCashForEmployees(uint256[] memory tokenIds) internal view returns (uint256[] memory);
```

### \_getTokenTimelock

```solidity
function _getTokenTimelock() internal view returns (ITokenTimelock);
```

### \_getCommonShares

```solidity
function _getCommonShares() internal view returns (address);
```

### approve

*Overridden ERC721 approve() such that approvals are disabled*

```solidity
function approve(address, uint256) public virtual override(ERC721Upgradeable, IERC721);
```

### transferFrom

*Overridden ERC721 transferFrom() such that transfers are disabled*

```solidity
function transferFrom(address, address, uint256) public virtual override(ERC721Upgradeable, IERC721);
```

### \_update

*Overridden ERC721 update such that burning is disabled*

```solidity
function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address);
```

### \_setApprovalForAll

```solidity
function _setApprovalForAll(address, address, bool) internal view virtual override;
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(ERC721Upgradeable, MezzEIP712, MezzUUPSUpgradeable, IERC165)
    returns (bool);
```

### onERC721Received

*Reference: <https://eips.ethereum.org/EIPS/eip-721>*

```solidity
function onERC721Received(address, address, uint256, bytes memory) public view virtual returns (bytes4);
```

### upgradeToNewerVersion

Upgrades 'this' to a newer version via the Mezz Migrator. Only callable by the Treasury, whose signers are the board of directors

*Will revert if the protocol state is 'Paused' or 'Frozen'*

```solidity
function upgradeToNewerVersion(uint256 newVersion, bytes memory data) public virtual onlyProxy onlyBoard;
```

**Parameters**

| Name         | Type      | Description                                                                                              |
| ------------ | --------- | -------------------------------------------------------------------------------------------------------- |
| `newVersion` | `uint256` | The new version to upgrade to                                                                            |
| `data`       | `bytes`   | The data to be passed to the new implementation, which likely should be a reinitializer function if used |

### \_authorizePatch

*Access control for 'resetToPatchedLatestVersion()'*

```solidity
function _authorizePatch(bytes memory) internal view virtual override;
```

## Structs

### PayrollManagerStorage

```solidity
struct PayrollManagerStorage {
    EnumerableSet.Bytes32Set _pendingActions;
    mapping(bytes32 => uint256) _snapshotByPendingActionId;
    mapping(uint256 => DataTypes.Salary) _salaryByTokenId;
}
```


# PricedRound

[Git Source](https://github.com/EntreDevelopers-Lab-Inc/Mezz-Companies/blob/f7a3e84e3dd5bb33c4bd7f77283983f9e8ba20b2/src/core/modules/equity-financing/priced-round/PricedRound.sol)

**Inherits:** Credentialed, StateAware, BoardControlled, IPricedRound

**Author:** Daniel Yamagata&#x20;

A contract for starting a priced round that emulates traditional priced rounds in Venture Capital financing

Priced rounds are deployed and instantiated by the Equity Financing module.  They are deployed via [OpenZeppelin Clones (i.e. ERC1167 Minimal Proxies)](<https://github.com/OpenZeppelin/openzeppelin-contracts/blob/9e3f4d60c581010c4a3979480e07cc7752f124cc/contracts/proxy/Clones.sol >).&#x20;

Invariants:

* The number of '\_shares' held by this contract is greater than or equal to the number of shares released
* The amount of the '\_denominationAsset' held by this contract is greater than or equal to the amount of the denomination asset released\*

## State Variables

### MIN\_INVESTOR\_ALLOCATION

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

### PricedRoundStorageLocation

```solidity
bytes32 private constant PricedRoundStorageLocation = 0xa7f784e00080c54058c6c75beccaf3cec18ab4699f88cfccb9370b9797cad800;
```

## Functions

### \_getPricedRoundStorage

```solidity
function _getPricedRoundStorage() internal pure returns (PricedRoundStorage storage $);
```

### constructor

```solidity
constructor(address _mezzHub) StateAware(_mezzHub);
```

### init

Opens a round and initializes the state variables

*Initializer. The shares must be supported by the treasury. Otherwise, this function will revert. The 'controller' of the contract will be the 'initTreasury'*

```solidity
function init(DataTypes.PricedRoundInitArgs memory initArgs, address initShares, address initTreasury)
    external
    virtual
    initializer
    pausable;
```

**Parameters**

| Name           | Type                            | Description                                                                                                                                       |
| -------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `initArgs`     | `DataTypes.PricedRoundInitArgs` | The arguments to initialize the round with                                                                                                        |
| `initShares`   | `address`                       | The shares to use for the round. The shares will be transferred to the Token Timelock or investors when claimed depending on the unlock arguments |
| `initTreasury` | `address`                       | The treasury to send the raised funds to when the round is closed                                                                                 |

### \_\_PricedRound\_init

```solidity
function __PricedRound_init(DataTypes.PricedRoundInitArgs memory initArgs, address initShares, address initTreasury)
    internal
    virtual
    onlyInitializing;
```

### unlockStartDate

```solidity
function unlockStartDate() public view returns (uint48);
```

### unlockDuration

Returns the unlock duration in seconds. Shares will be unlocked linearly over this period once claimed via the Token Timelock

```solidity
function unlockDuration() public view returns (uint32);
```

### unlockCliff

Returns the unlock cliff in seconds. The 'initialUnlock' will be unlocked once this cliff has passed

```solidity
function unlockCliff() public view returns (uint32);
```

### initialUnlockPercentage

The percentage of shares that will be unlocked initially once the 'unlockCliff' has passed

*All percentages are denominated in Constants.PRECISION\_FACTOR, which is 100\_000*

```solidity
function initialUnlockPercentage() public view returns (uint32);
```

### minimumRaise

The minimum amount of funds to be raised for the round for it to be able to be closed. Can be extended with increaseMinimumRaise()

*Returns the value in the units of the denomination asset. Must divide by the units on a frontend to get the nominal value*

```solidity
function minimumRaise() public view returns (uint128);
```

### targetRaise

The maximum amount of funds to be raised. Can be extended with extendRound()

*Returns the value in the units of the denomination asset. Must divide by the units on a frontend to get the nominal value*

```solidity
function targetRaise() public view returns (uint128);
```

### shares

The shares used for the round. Transferred to either the Token Timelock or an investor when claimed depending on the unlock arguments

```solidity
function shares() public view returns (address);
```

### allottedShares

The cumulative amount of shares that have been allotted to investors who have contributed to the round. Allotted shares does not account for allocations

```solidity
function allottedShares() public view returns (uint128);
```

### totalSharesForRound

The number of shares allocated to the round

```solidity
function totalSharesForRound() public view returns (uint128);
```

### totalRaised

The current total amount of funds raised in the units of the denomination asset

*Must divide by the units on a frontend to get the nominal value*

```solidity
function totalRaised() public view returns (uint128);
```

### denominationAsset

The denomination asset of the round. Used by the investor to invest in the round.

```solidity
function denominationAsset() public view returns (address);
```

### pricePerShare

The price per share of the round in the units of the 'denominationAsset'

*Must divide by the units on a frontend to get the nominal value*

```solidity
function pricePerShare() public view returns (uint96);
```

### roundState

Returns the state of the round as a RoundState enum:

* 0: Open
* 1: Closed
* 2: Filled
* 3: Canceled

```solidity
function roundState() public view virtual returns (DataTypes.RoundState);
```

### increaseMinimumRaise

Increases the minimum raise by 'minimumRaiseExtension'. The new minimum raise must be less than the target raise. This function can only be called if the round is 'Open' or 'Filled'. This function should be used cautiously: the minimum raise cannot be decreased once increased

*This function will revert if the sum of 'minimumRaise' and 'minimumRaiseExtension' is greater than type(uint128).max*

```solidity
function increaseMinimumRaise(uint128 minimumRaiseExtension) external virtual onlyBoard pausable;
```

**Parameters**

| Name                    | Type      | Description                                 |
| ----------------------- | --------- | ------------------------------------------- |
| `minimumRaiseExtension` | `uint128` | The amount to increase the minimum raise by |

### extendRound

Cache

*This function will revert if the sum of 'targetRaiseExtension' and 'targetRaise' or the sum of 'totalSharesExtensiion' and 'totalSharesForRound' are greater than uint128, which is extremely unlikely*

```solidity
function extendRound(uint128 targetRaiseExtension, uint128 totalSharesExtension) external virtual onlyBoard pausable;
```

**Parameters**

| Name                   | Type      | Description                                     |
| ---------------------- | --------- | ----------------------------------------------- |
| `targetRaiseExtension` | `uint128` | The amount to increase 'targetRaise' by         |
| `totalSharesExtension` | `uint128` | The amount to increase 'totalSharesForRound' by |

### cancelRound

Cache

*A round can only be canceled only if it is 'Open' or 'Filled'*

```solidity
function cancelRound() external virtual onlyBoard freezable;
```

### closeRound

Cache

*A round can only be closed only if it is 'Open' or 'Filled'. The 'totalRaised' must be greater than or equal to the 'minimumRaise'. Otherwise, this function will revert.*

```solidity
function closeRound() external virtual onlyBoard freezable;
```

### setInvestorAllocation

Delete unnecessary vars that are only used when a round is 'open

*Once set, an allocation should not be reset using this function. It should be increased or decreased by 'increaseInvestorAllocation' and 'decreaseInvestorAllocation' accordingly. Otherwise, the investor is capable of frontrunning any changes to their allocation via this function.*

```solidity
function setInvestorAllocation(address investor, DataTypes.Allocation memory allocation) external virtual onlyBoard;
```

**Parameters**

| Name         | Type                   | Description                                                                            |
| ------------ | ---------------------- | -------------------------------------------------------------------------------------- |
| `investor`   | `address`              | The investor to set the allocation for                                                 |
| `allocation` | `DataTypes.Allocation` | The allocation to set, which includes the number of shares and the discount or premium |

### increaseInvestorShareAllocation

Increases the investor's share allocation by the specified amount. Only callable by the 'owner'

*Used to avoid race conditions. Repeated use of 'setInvestorAllocation' could lead to exploitation similar to how a malicious actor can exploit 'approve' in place of 'increaseAllowance' for ERC20s*

```solidity
function increaseInvestorShareAllocation(address investor, uint128 amount) external virtual onlyBoard;
```

**Parameters**

| Name       | Type      | Description                                 |
| ---------- | --------- | ------------------------------------------- |
| `investor` | `address` | The investor to increase the allocation for |
| `amount`   | `uint128` | The amount to increase the allocation by    |

### decreaseInvestorShareAllocation

Decreases the investor's share allocation by the specified amount. Only callable by the 'owner'

*Used to avoid race conditions.*

```solidity
function decreaseInvestorShareAllocation(address investor, uint128 amount) external virtual onlyBoard;
```

**Parameters**

| Name       | Type      | Description                                 |
| ---------- | --------- | ------------------------------------------- |
| `investor` | `address` | The investor to decrease the allocation for |
| `amount`   | `uint128` | The amount to decrease the allocation by    |

### investInRound

Transfers the investor's allocation from the investor to this contract. Allots their owed shares accordingly

*'expectedDiscountOrPremium' and 'expectedNumberOfShares' is used to avoid frontrunning attacks by the company. Otherwise, the owner can frontrun the investor by calling 'setInvestorAllocation' and increase their premium or number of shares unknowingly*

```solidity
function investInRound(uint128 expectedNumberOfShares, int128 expectedDiscountOrPremium) external virtual pausable;
```

**Parameters**

| Name                        | Type      | Description                                                    |
| --------------------------- | --------- | -------------------------------------------------------------- |
| `expectedNumberOfShares`    | `uint128` | The number of shares that the investor is expecting to receive |
| `expectedDiscountOrPremium` | `int128`  | The price per share that the investor is expecting to pay      |

### claimShares

Calculate the amount of the denom asset to transfer that it will be negligible to the round. However, it is still accounted for Update state

*Shares are claimable only if the round is 'Closed'*

```solidity
function claimShares(address investor) external virtual freezable returns (uint256);
```

**Returns**

| Name     | Type      | Description                                                                                                              |
| -------- | --------- | ------------------------------------------------------------------------------------------------------------------------ |
| `<none>` | `uint256` | The ERC721 token ID for the vesting shares in the Token Timelock. Returns 0 if the shares are not susceptible to vesting |

### revokeInvestment

Sends the caller's investment back to them, forgoing their shares in the round.  The round must be 'Open' or 'Filled'

*Will revert if the caller does not have an investment*

```solidity
function revokeInvestment() external virtual freezable;
```

### recoupInvestment

Withdraws the investment of the 'investor' for a 'Canceled' round. This function is callable by anyone. Anyone can recoup an investor's investment on their behalf.

```solidity
function recoupInvestment(address investor) external virtual freezable;
```

**Parameters**

| Name       | Type      | Description                               |
| ---------- | --------- | ----------------------------------------- |
| `investor` | `address` | The investor to recoup the investment for |

### calculateAdjustedPricePerShare

Returns the adjusted price per share given the 'discountOrPremium'

```solidity
function calculateAdjustedPricePerShare(int256 discountOrPremium) external view returns (uint256);
```

**Parameters**

| Name                | Type     | Description                                             |
| ------------------- | -------- | ------------------------------------------------------- |
| `discountOrPremium` | `int256` | The discount or premium to apply to the price per share |

### remainingShares

Returns the remaining shares that can be allotted to investors

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

### remainingDenominationAsset

Returns the remaining denomination asset that can be raised

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

### getInvestors

Returns all the investors who have contributed to the round

```solidity
function getInvestors() public view returns (address[] memory);
```

**Returns**

| Name     | Type        | Description                              |
| -------- | ----------- | ---------------------------------------- |
| `<none>` | `address[]` | The investors as an address memory array |

### getAllocatedAddresses

Returns all addresses that currently have an allocation

```solidity
function getAllocatedAddresses() public view returns (address[] memory);
```

**Returns**

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

### getInvestment

Returns the investment of the 'investor', which includes their investment amount and the shares they are owed

```solidity
function getInvestment(address investor) public view returns (DataTypes.Investment memory);
```

**Returns**

| Name     | Type                   | Description                                     |
| -------- | ---------------------- | ----------------------------------------------- |
| `<none>` | `DataTypes.Investment` | The investment as a DataTypes.Investment struct |

### getAllocation

Returns the allocation of the 'investor', which includes the number of shares they are allocated and their discount or premium

```solidity
function getAllocation(address investor) public view returns (DataTypes.Allocation memory);
```

**Returns**

| Name     | Type                   | Description                                     |
| -------- | ---------------------- | ----------------------------------------------- |
| `<none>` | `DataTypes.Allocation` | The allocation as a DataTypes.Allocation struct |

### getInvestmentAmountForAllocation

Returns the implied investment amount in the denomination asset for the allocation of the 'investor'

*Returns the value in the units of the denomination asset. Must divide by the units on a frontend to get the nominal value*

```solidity
function getInvestmentAmountForAllocation(address investor) public view returns (uint256);
```

### getImpliedOutstandingValuation

Returns the implied pre-money outstanding valuation of the company in the denomination asset

*Returns the value in the units of the denomination asset. Must divide by the units on a frontend to get the nominal value*

```solidity
function getImpliedOutstandingValuation() public view virtual returns (uint256);
```

**Returns**

| Name     | Type      | Description           |
| -------- | --------- | --------------------- |
| `<none>` | `uint256` | The implied valuation |

### getImpliedFullyDilutedValuation

Returns the implied pre-money fully diluted valuation of the company in the denomination asset

*Returns the value in the units of the denomination asset. Must divide by the units on a frontend to get the nominal value*

```solidity
function getImpliedFullyDilutedValuation() public view virtual returns (uint256);
```

**Returns**

| Name     | Type      | Description           |
| -------- | --------- | --------------------- |
| `<none>` | `uint256` | The implied valuation |

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```

### supportsInterface

*See {IERC165-supportsInterface}.*

```solidity
function supportsInterface(bytes4 interfaceId) public view virtual override(Credentialed, IERC165) returns (bool);
```

### \_reverseInvestment

*Sends the investor's investment back to them. Updates state accordingly*

```solidity
function _reverseInvestment(address investor) internal virtual returns (DataTypes.Investment memory);
```

**Returns**

| Name     | Type                   | Description               |
| -------- | ---------------------- | ------------------------- |
| `<none>` | `DataTypes.Investment` | The investor's investment |

### \_calculateInvestmentAmount

Update state

*The 'pricePerShare' is in the denomination asset's units. We make the necessary adjustments here*

```solidity
function _calculateInvestmentAmount(address sharesCache, uint256 numberOfShares, uint256 adjustedPricePerShare)
    internal
    view
    returns (uint256);
```

### \_calculateAdjustedPricePerShare

*'discountOrPremium' implictly converted from a int128 to a int256*

```solidity
function _calculateAdjustedPricePerShare(int256 discountOrPremium) internal view virtual returns (uint256);
```

### \_deleteAllocations

*Deletes all the allocations*

```solidity
function _deleteAllocations() internal;
```

### \_validateRoundStateOpen

*Validates that the round state is 'Open'*

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

### \_validateRoundStateOpenOrFilled

*Validates that the round state is 'Open' or 'Filled'*

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

### \_validateInitArgs

```solidity
function _validateInitArgs(DataTypes.PricedRoundInitArgs memory initArgs) internal pure;
```

### \_validateRaiseAmounts

*Validates that the '\_minimumRaise' is less than or equal to the '\_targetRaise'*

```solidity
function _validateRaiseAmounts(uint256 _minimumRaise, uint256 _targetRaise) internal pure;
```

### \_validateDiscountOrPremium

*Validates a 'discountOrPremium' value. A negative value is a discount, and a positive value is a premium A discount should never be below 100% (i.e. Constants.PRECISION\_FACTOR), while a premium should never be above 500% (i.e. 5 \* Constants.PRECISION\_FACTOR)*

```solidity
function _validateDiscountOrPremium(int256 discountOrPremium) internal pure;
```

### \_checkInvariants

*Asserts that the cumulative shares and denomination asset deposited is greater than or equal to the cumulative shares and denomination asset released, respectively*

```solidity
function _checkInvariants(address sharesCache, address denomAssetCache) internal view virtual;
```

## Structs

### PricedRoundStorage

```solidity
struct PricedRoundStorage {
    uint128 _minimumRaise;
    uint128 _targetRaise;
    address _shares;
    bool _open;
    bool _cancelled;
    uint32 _unlockDuration;
    uint48 _unlockStartDate;
    uint32 _unlockCliff;
    uint32 _initialUnlockPercentage;
    uint128 _allottedShares;
    uint128 _totalSharesForRound;
    uint128 _totalRaised;
    address _denominationAsset;
    uint96 _pricePerShare;
    EnumerableSet.AddressSet _investors;
    EnumerableSet.AddressSet _allocated;
    mapping(address => DataTypes.Allocation) _allocationByInvestor;
    mapping(address => DataTypes.Investment) _investmentByInvestor;
    mapping(address => uint256) _erc20Invested;
    mapping(address => uint256) _erc20Released;
}
```


# MezzGovernor

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

**Inherits:** StateAware, Patchable, IMezzGovernor

**Author:** Daniel Yamagata

A base contract for governor that defines upgradeability logic and modifiers for access control

*All governors are able to execute arbitrary transactions. Therefore, they are able to call the Mezz Migrator to upgrade themselves to a newer version. Specifically, the governor should call the Mezz Migrator's upgradeToNewerVersion() However, resetting to a patched version may not be possible depending on the protocol state. Therefore, a function to execute this callback is provided via 'Patchable'*

## State Variables

### MezzGovernorStorageLocation

```solidity
bytes32 private constant MezzGovernorStorageLocation =
    0x0b1a6379e7855c565527499b30056eabdaf3a2b55abb1e5da911b250c18bf800;
```

## Functions

### \_getMezzGovernorStorage

```solidity
function _getMezzGovernorStorage() internal pure returns (MezzGovernorStorage storage $);
```

### constructor

```solidity
constructor(address _mezzHub, address _mezzMigrator) StateAware(_mezzHub) Patchable(_mezzMigrator);
```

### onlyMezzGovernance

*Reverts if the caller is not 'this'*

```solidity
modifier onlyMezzGovernance();
```

### init

Intializes the Governor's state

```solidity
function init(address initTreasury, bytes memory params) external virtual;
```

**Parameters**

| Name           | Type      | Description                                                   |
| -------------- | --------- | ------------------------------------------------------------- |
| `initTreasury` | `address` | The address of the Treasury that the Governor is in charge of |
| `params`       | `bytes`   | Bespoke abi.encoded parameters                                |

### \_\_MezzGovernor\_init

```solidity
function __MezzGovernor_init(address initTreasury) internal virtual onlyInitializing;
```

### treasury

Returns the address of the treasury associated with the governor

```solidity
function treasury() public view virtual returns (address);
```

### name

Returns the name of the governor

```solidity
function name() public view virtual returns (string memory);
```

### \_validateCallerIsGovernance

*Reverts if the caller is not 'this'*

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

### \_authorizePatch

*Access control for 'resetToPatchedLatestVersion()'*

```solidity
function _authorizePatch(bytes memory) internal view override;
```

## Structs

### MezzGovernorStorage

```solidity
struct MezzGovernorStorage {
    address _treasury;
}
```


# ProposalGovernor

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

**Inherits:** ContextUpgradeable, MezzGovernor, MezzEIP712, NoncesUpgradeable, IProposalGovernor

**Author:** Daniel Yamagata

A base class that provides functionality for on-chain proposals and voting. This contract does not implement the execution of proposals

*This contract is heavily inspired by* [*OpenZeppelin's Governor contract*](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/7294d34c17ca215c201b3772ff67036fa4b1ef12/contracts/governance/Governor.sol)*.*

## State Variables

### \_BALLOT\_TYPEHASH

```solidity
bytes32 internal constant _BALLOT_TYPEHASH =
    keccak256("Ballot(uint256 proposalId,uint8 support,address voter,uint256 nonce)");
```

### \_EXTENDED\_BALLOT\_TYPEHASH

```solidity
bytes32 internal constant _EXTENDED_BALLOT_TYPEHASH =
    keccak256("ExtendedBallot(uint256 proposalId,uint8 support,address voter,uint256 nonce,string reason,bytes params)");
```

### SUPER\_MAJORITY\_PERCENTAGE

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

### ProposalGovernorStorageLocation

```solidity
bytes32 private constant ProposalGovernorStorageLocation =
    0x1f64e26c32eddaf99df35a9898d9e2c7b2a05db947531695b541d0030f865a00;
```

## Functions

### \_getProposalGovernorStorage

```solidity
function _getProposalGovernorStorage() internal pure returns (ProposalGovernorStorage storage $);
```

### \_\_ProposalGovernor\_init

```solidity
function __ProposalGovernor_init() internal onlyInitializing;
```

### setQuorumPercentage

Sets a new quourm percentage

*Only callable via governance itself*

```solidity
function setQuorumPercentage(uint256 newQuorumPercentage) external onlyMezzGovernance;
```

**Parameters**

| Name                  | Type      | Description               |
| --------------------- | --------- | ------------------------- |
| `newQuorumPercentage` | `uint256` | The new quorum percentage |

### setProposalThresholdPercentage

Sets a new proposal threshold percentage

*Only callable via governance itself*

```solidity
function setProposalThresholdPercentage(uint256 newProposalThresholdPercentage) external onlyMezzGovernance;
```

**Parameters**

| Name                             | Type      | Description                           |
| -------------------------------- | --------- | ------------------------------------- |
| `newProposalThresholdPercentage` | `uint256` | The new proposal threshold percentage |

### setVotingDelay

Sets a new voting delay

*Only callable via governance itself*

```solidity
function setVotingDelay(uint256 newVotingDelay) external onlyMezzGovernance;
```

**Parameters**

| Name             | Type      | Description          |
| ---------------- | --------- | -------------------- |
| `newVotingDelay` | `uint256` | The new voting delay |

### setVotingPeriod

Sets a new voting period

*Only callable via governance itself*

```solidity
function setVotingPeriod(uint256 newVotingPeriod) external onlyMezzGovernance;
```

**Parameters**

| Name              | Type      | Description           |
| ----------------- | --------- | --------------------- |
| `newVotingPeriod` | `uint256` | The new voting period |

### castVote

Casts the caller's votes towards the proposal associated with 'proposalId' There are three different vote types defined by the following enum:

* 0: Against
* 1: For
* 2: Abstain

*A voter can only vote once and cannot revoke or change their vote. Votes are calculated from the proposal's snapshot and the counting of votes is bespoke and must be implemented by the inheritor*

```solidity
function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `proposalId` | `uint256` | The ID of the proposal to cast the vote for |
| `support`    | `uint8`   | The vote type                               |

**Returns**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `<none>` | `uint256` | The number of votes of the caller |

### castVoteWithReason

Casts the caller's votes with a 'reason' towards the proposal associated with 'proposalId'

*The 'reason' is not stored on-chain but, rather, emitted in an event*

```solidity
function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason)
    public
    virtual
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `proposalId` | `uint256` | The ID of the proposal to cast the vote for |
| `support`    | `uint8`   | The vote type                               |
| `reason`     | `string`  | The reason for the vote                     |

**Returns**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `<none>` | `uint256` | The number of votes of the caller |

### castVoteWithReasonAndParams

Casts the caller's votes with a 'reason' and 'params' towards the proposal associated with 'proposalId'

*'params' are bespoke, abi-encoded arguments that could be used for casting a vote*

```solidity
function castVoteWithReasonAndParams(uint256 proposalId, uint8 support, string calldata reason, bytes memory params)
    public
    virtual
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `proposalId` | `uint256` | The ID of the proposal to cast the vote for |
| `support`    | `uint8`   | The vote type                               |
| `reason`     | `string`  | The reason for the vote                     |
| `params`     | `bytes`   | The abi-encoded parameters for the vote     |

**Returns**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `<none>` | `uint256` | The number of votes of the caller |

### castVoteBySig

Casts the votes of 'voter' towards the proposal associated with 'proposalId' via an EIP-712 signature

*Reference: <https://eips.ethereum.org/EIPS/eip-712>*

```solidity
function castVoteBySig(uint256 proposalId, uint8 support, address voter, bytes memory signature)
    public
    virtual
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `proposalId` | `uint256` | The ID of the proposal to cast the vote for |
| `support`    | `uint8`   | The vote type                               |
| `voter`      | `address` | The address of the voter                    |
| `signature`  | `bytes`   | The EIP-712 signature of the voter          |

**Returns**

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `<none>` | `uint256` | The number of votes of the voter |

### castVoteWithReasonAndParamsBySig

Casts the votes of 'voter' towards the proposal associated with 'proposalId' via an EIP-712 signature

\_Reference: <https://eips.ethereum.org/EIPS/eip-712_&#x20>;

*'params' are bespoke, abi-encoded arguments that could be used for casting a vote*

```solidity
function castVoteWithReasonAndParamsBySig(
    uint256 proposalId,
    uint8 support,
    address voter,
    string calldata reason,
    bytes memory params,
    bytes memory signature
) public virtual returns (uint256);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `proposalId` | `uint256` | The ID of the proposal to cast the vote for |
| `support`    | `uint8`   | The vote type                               |
| `voter`      | `address` | The address of the voter                    |
| `reason`     | `string`  | The reason for the vote                     |
| `params`     | `bytes`   | The abi-encoded parameters for the vote     |
| `signature`  | `bytes`   | The EIP-712 signature of the voter          |

**Returns**

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `<none>` | `uint256` | The number of votes of the voter |

### \_castVote

```solidity
function _castVote(uint256 proposalId, address account, uint8 support, string memory reason)
    internal
    virtual
    returns (uint256);
```

### \_castVote

*Overridden by inheriting contracts. Inheritors should query votes and count them towards a proposal*

```solidity
function _castVote(uint256 proposalId, address account, uint8 support, string memory reason, bytes memory params)
    internal
    virtual
    returns (uint256);
```

### state

Returns the state of a proposal associated with 'proposalId' as a ProposalState enum

```solidity
function state(uint256 proposalId) public view virtual returns (IModifiedGovernor.ProposalState);
```

### hasVoted

Returns true if 'account' has voted on a proposal with 'proposalId', false otherwise

```solidity
function hasVoted(uint256 proposalId, address account) public view virtual returns (bool);
```

**Returns**

| Name     | Type   | Description                                    |
| -------- | ------ | ---------------------------------------------- |
| `<none>` | `bool` | True if the account has voted, false otherwise |

### getReceipt

Returns the voting receipt of 'account' for the proposal with 'proposalId'

```solidity
function getReceipt(uint256 proposalId, address account) external view returns (DataTypes.Receipt memory);
```

**Returns**

| Name     | Type                | Description                                              |
| -------- | ------------------- | -------------------------------------------------------- |
| `<none>` | `DataTypes.Receipt` | The receipt of the account as a DataTypes.Receipt struct |

### getProposalVotes

Returns the total votes for the proposal with 'proposalId'

```solidity
function getProposalVotes(uint256 proposalId) external view returns (DataTypes.ProposalVotes memory);
```

**Returns**

| Name     | Type                      | Description                                                          |
| -------- | ------------------------- | -------------------------------------------------------------------- |
| `<none>` | `DataTypes.ProposalVotes` | The total votes for the proposal as a DataTypes.ProposalVotes struct |

### votingDelay

Returns the voting delay in seconds

```solidity
function votingDelay() public view virtual returns (uint256);
```

**Returns**

| Name     | Type      | Description                 |
| -------- | --------- | --------------------------- |
| `<none>` | `uint256` | The voting delay in seconds |

### votingPeriod

Returns the voting period

```solidity
function votingPeriod() public view virtual returns (uint256);
```

**Returns**

| Name     | Type      | Description                  |
| -------- | --------- | ---------------------------- |
| `<none>` | `uint256` | The voting period in seconds |

### quorumPercentage

Returns the quorum percentage

```solidity
function quorumPercentage() public view virtual returns (uint256);
```

**Returns**

| Name     | Type      | Description                                              |
| -------- | --------- | -------------------------------------------------------- |
| `<none>` | `uint256` | The quorum percentage multiplied by the precision factor |

### proposalThresholdPercentage

Returns the proposal threshold percentage

```solidity
function proposalThresholdPercentage() public view virtual returns (uint256);
```

**Returns**

| Name     | Type      | Description                                                          |
| -------- | --------- | -------------------------------------------------------------------- |
| `<none>` | `uint256` | The proposal threshold percentage multiplied by the precision factor |

### getBallotTransactionHash

Returns the ballot transaction hash, which is used in casting votes by signature

*The returned transaction hash should be signed by the voter to create a valid signature Reference: <https://eips.ethereum.org/EIPS/eip-712>*

```solidity
function getBallotTransactionHash(uint256 proposalId, uint8 support, address voter, uint256 nonce)
    public
    view
    virtual
    returns (bytes32);
```

### getBallotStructHash

Return the ballot struct hash

*Reference: <https://eips.ethereum.org/EIPS/eip-712>*

```solidity
function getBallotStructHash(uint256 proposalId, uint8 support, address voter, uint256 nonce)
    public
    view
    virtual
    returns (bytes32);
```

### getExtendedBallotTransactionHash

Returns the extended ballot transaction hash, which is used in casting votes with reasons and params by signature

*The returned transaction hash should be signed by the voter to create a valid signature Reference: <https://eips.ethereum.org/EIPS/eip-712>*

```solidity
function getExtendedBallotTransactionHash(
    uint256 proposalId,
    uint8 support,
    address voter,
    uint256 nonce,
    string memory reason,
    bytes memory params
) public view virtual returns (bytes32);
```

### getExtendedBallotStructHash

Returns the extended ballot struct hash

*Reference: <https://eips.ethereum.org/EIPS/eip-712>*

```solidity
function getExtendedBallotStructHash(
    uint256 proposalId,
    uint8 support,
    address voter,
    uint256 nonce,
    string memory reason,
    bytes memory params
) public view virtual returns (bytes32);
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```

### clock

*EIP-6372 support*

```solidity
function clock() public view virtual returns (uint48);
```

### CLOCK\_MODE

*EIP-6372 support*

```solidity
function CLOCK_MODE() public view virtual returns (string memory);
```

### \_countVote

*Counts a vote for a given proposal. Sets the receipt in storage Assumes that the weight has already been calculated*

```solidity
function _countVote(uint256 proposalId, address account, uint8 support, uint256 votes, bytes memory) internal virtual;
```

### \_voteSucceeded

*Returns whether or not the vote succeeded for a given proposal*

```solidity
function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool);
```

**Returns**

| Name     | Type   | Description                                                               |
| -------- | ------ | ------------------------------------------------------------------------- |
| `<none>` | `bool` | True if the for votes are greater than the against votes, false otherwise |

### supportsInterface

*EIP-165 support. Reference: <https://eips.ethereum.org/EIPS/eip-165>*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(MezzEIP712, MezzUUPSUpgradeable, IERC165)
    returns (bool);
```

## Structs

### ProposalGovernorStorage

```solidity
struct ProposalGovernorStorage {
    uint256 _proposalThresholdPercentage;
    uint256 _quorumPercentage;
    uint256 _votingPeriod;
    uint256 _votingDelay;
    mapping(uint256 => DataTypes.ProposalVotes) _proposalVotes;
    mapping(uint256 => mapping(address => DataTypes.Receipt)) _receipts;
}
```


# StartupGovernor

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

**Inherits:** MezzGovernor, MezzEIP712, NoncesUpgradeable, IStartupGovernor

**Author:** Daniel Yamagata

A governance contract that enables the execution of arbitrary transactions by a super-majority of a treasury's signers. A super majority is counted as two-thirds of the signers rounded upwards. Below is a table with a few examples.

| Signers | Super Majority |
| ------- | -------------- |
| 2       | 2              |
| 3       | 2              |
| 4       | 3              |
| 5       | 4              |
| 6       | 4              |

*The execution of transactions requires an arbitrary deadline. If this deadline passes, the transaction will revert even if provided the correct number of signatures.*

## State Variables

### EXECUTE\_TYPEHASH

```solidity
bytes32 public constant EXECUTE_TYPEHASH =
    keccak256("Execute(address target,uint256 value,bytes data,uint256 deadline,uint256 nonce)");
```

## Functions

### constructor

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

### init

Intializes the Governor's state

```solidity
function init(address initTreasury, bytes memory) external virtual override initializer;
```

**Parameters**

| Name           | Type      | Description                                                   |
| -------------- | --------- | ------------------------------------------------------------- |
| `initTreasury` | `address` | The address of the Treasury that the Governor is in charge of |
| `<none>`       | `bytes`   |                                                               |

### \_\_Startup\_Governor\_init

*The 'params' argument is maintained in case future versions require additional initialization parameters*

```solidity
function __Startup_Governor_init(address initTreasury, bytes memory) internal virtual onlyInitializing;
```

### executeTx

Executes an arbitrary transaction. Requires a super majority of board members to sign off

*Signatures must be packed in ascending order of the public addresses of the signers and must be packed into a single variable.*

```solidity
function executeTx(address target, uint256 value, bytes memory data, bytes memory signatures, uint256 deadline)
    public
    virtual
    freezable
    returns (bytes memory);
```

**Parameters**

| Name         | Type      | Description                                                |
| ------------ | --------- | ---------------------------------------------------------- |
| `target`     | `address` | The target address to execute the transaction on           |
| `value`      | `uint256` | The amount of native currency to send with the transaction |
| `data`       | `bytes`   | The calldata of the transaction                            |
| `signatures` | `bytes`   | The signatures of the board members                        |
| `deadline`   | `uint256` |                                                            |

**Returns**

| Name     | Type    | Description                        |
| -------- | ------- | ---------------------------------- |
| `<none>` | `bytes` | The return data of the transaction |

### \_checkNSignatures

*Validates the 'signatures' and the number of required signatures for 'safeCache', '\_hash', and '\_hashData'*

```solidity
function _checkNSignatures(address safeCache, bytes32 dataHash, bytes memory signatures, uint256 requiredSigs)
    internal
    view
    virtual;
```

### \_execute

*Executes a call on a given 'target' with 'data' and 'value'. Reverts if the call fails or the target's code length is zero*

```solidity
function _execute(address target, uint256 value, bytes memory data) internal virtual returns (bytes memory);
```

### getExecuteTransactionHash

Returns the transaction hash of the encoded execute data.

*This hash is the one to be signed by a private key. Signatures should then be packed in ascending order by the public keys of the owners when calling executeTx()*

```solidity
function getExecuteTransactionHash(DataTypes.StartupGovernorExecute memory execute)
    public
    view
    virtual
    returns (bytes32);
```

**Parameters**

| Name      | Type                               | Description                               |
| --------- | ---------------------------------- | ----------------------------------------- |
| `execute` | `DataTypes.StartupGovernorExecute` | The StartupGovernorExecute struct to hash |

### encodeExecuteData

Encodes a StartupGovernorExecute struct hash following the EIP-191 signed typed data standard

*Reference: <https://eips.ethereum.org/EIPS/eip-191>*

```solidity
function encodeExecuteData(DataTypes.StartupGovernorExecute memory execute)
    public
    view
    virtual
    returns (bytes memory);
```

**Parameters**

| Name      | Type                               | Description                                                       |
| --------- | ---------------------------------- | ----------------------------------------------------------------- |
| `execute` | `DataTypes.StartupGovernorExecute` | The StartupGovernorExecute struct to hash and subsequently encode |

### getExecuteStructHash

Returns the hash of a StartupGovernorExecute struct following the EIP-712 encoding standards

*Reference: <https://eips.ethereum.org/EIPS/eip-712>*

```solidity
function getExecuteStructHash(DataTypes.StartupGovernorExecute memory execute) public view virtual returns (bytes32);
```

**Parameters**

| Name      | Type                               | Description                               |
| --------- | ---------------------------------- | ----------------------------------------- |
| `execute` | `DataTypes.StartupGovernorExecute` | The StartupGovernorExecute struct to hash |

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```

### onERC721Received

*Reference: <https://eips.ethereum.org/EIPS/eip-721>*

```solidity
function onERC721Received(address, address, uint256, bytes memory) public view virtual returns (bytes4);
```

### onERC1155Received

*Reference: <https://eips.ethereum.org/EIPS/eip-1155>*

```solidity
function onERC1155Received(address, address, uint256, uint256, bytes memory) public view virtual returns (bytes4);
```

### onERC1155BatchReceived

*Reference: <https://eips.ethereum.org/EIPS/eip-1155>*

```solidity
function onERC1155BatchReceived(address, address, uint256[] memory, uint256[] memory, bytes memory)
    public
    view
    virtual
    returns (bytes4);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(MezzEIP712, MezzUUPSUpgradeable, IERC165)
    returns (bool);
```


# ShareClassGovernor

[Git Source](https://github.com/EntreDevelopers-Lab-Inc/Mezz-Companies/blob/f7a3e84e3dd5bb33c4bd7f77283983f9e8ba20b2/src/core/governance/share-class/ShareClassGovernor.sol)

**Inherits:** StartupGovernor, ProposalGovernor, IShareClassGovernor

**Author:** Daniel Yamagata

A governance contract that enables the execution of arbitrary transactions by a super-majority of a treasury's signers. However, the management of the treasury's board members requires a proposal proccess. A preferred share class can be allocated control of up to three board seats, while the common shares do not have a limit on the number of seats that can be allocated. Once allocated, seats cannot be decreased. For example, if Preferred Shares Class A is allocated control over 2 board seats, its allocation cannot be decreased to 1 board seat. The allocation of seats is done directly by the board of directors. However, the assignment of the allocated board seats is left to the proposal process.

*The following contract is heavily based on OZ's Governor Upgradeable, the Late Stage governor, and the Startup Governor The primary difference is proposals are fragmented by share classes. Therefore, direct inheritance from OZ's governor was not possible*

## State Variables

### BALLOT\_TYPEHASH

```solidity
bytes32 public constant BALLOT_TYPEHASH = _BALLOT_TYPEHASH;
```

### EXTENDED\_BALLOT\_TYPEHASH

```solidity
bytes32 public constant EXTENDED_BALLOT_TYPEHASH = _EXTENDED_BALLOT_TYPEHASH;
```

### ShareClassGovernorStorageLocation

```solidity
bytes32 private constant ShareClassGovernorStorageLocation =
    0x562a9c0a18060dac6c99104dbc22c3187c8da12ab6cbbc0788d567773f540f00;
```

## Functions

### \_getShareClassGovernorStorage

```solidity
function _getShareClassGovernorStorage() internal pure returns (ShareClassGovernorStorage storage $);
```

### constructor

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

### init

Intializes the Governor's state

```solidity
function init(address initTreasury, bytes memory)
    external
    virtual
    override(StartupGovernor, MezzGovernor, IMezzGovernor)
    initializer;
```

**Parameters**

| Name           | Type      | Description                                                   |
| -------------- | --------- | ------------------------------------------------------------- |
| `initTreasury` | `address` | The address of the Treasury that the Governor is in charge of |
| `<none>`       | `bytes`   |                                                               |

### \_\_ShareClassGovernor\_init

*The 'params' argument is maintained in case future versions require additional initialization parameters*

```solidity
function __ShareClassGovernor_init(address initTreasury, bytes memory) internal virtual onlyInitializing;
```

### state

Returns the state of a proposal associated with 'proposalId' as a ProposalState enum

```solidity
function state(uint256 proposalId)
    public
    view
    virtual
    override(ProposalGovernor, IProposalGovernor)
    returns (IModifiedGovernor.ProposalState);
```

### increaseBoardSeatsForShareClass

Increases the board seats for a given share class.&#x20;

*This function should be called with caution: the number of board seats for a given share class cannot be decreased. Only callable by governance, itself.*

```solidity
function increaseBoardSeatsForShareClass(address shareClass, uint256 increaseAmount)
    external
    virtual
    onlyMezzGovernance
    freezable;
```

**Parameters**

| Name             | Type      | Description                                               |
| ---------------- | --------- | --------------------------------------------------------- |
| `shareClass`     | `address` | The share class to increase the allocated board seats for |
| `increaseAmount` | `uint256` | The amount to increase the allocated board seats by       |

### proposeBoardMemberChange

Proposes a board member change for a given 'shareClass'.  The 'action' must be releated to adding a board member, removing a board member, or swapping a board member. &#x20;

*If the threshold is n, where n is the total number of board members, the new threshold will be n - 1.  Otherwise, the threshold of the treasury will not change.  The 'action' needs to be one that manages the owners of a team. These are defined in \_validateAction(...)*

```solidity
function proposeBoardMemberChange(address shareClass, bytes4 action, bytes memory params, string memory description)
    public
    virtual
    freezable
    returns (uint256);
```

**Parameters**

| Name          | Type      | Description                                          |
| ------------- | --------- | ---------------------------------------------------- |
| `shareClass`  | `address` | The share class to propose a board member change for |
| `action`      | `bytes4`  | The action for managing the treasury's owners        |
| `params`      | `bytes`   | The abi.encoded parameters for the given 'action'    |
| `description` | `string`  | The description of the proposal                      |

**Returns**

| Name     | Type      | Description     |
| -------- | --------- | --------------- |
| `<none>` | `uint256` | The proposal ID |

### cancelProposal

Cancels a pending proposal for 'shareClass'. &#x20;

*The caller must be the Proposal's proposer or the Mezz Hub's owner. The params are solely used to re-create the proposal's ID*

```solidity
function cancelProposal(address shareClass, bytes4 action, bytes memory params, bytes32 descriptionHash)
    public
    virtual
    freezable
    returns (uint256);
```

**Returns**

| Name     | Type      | Description     |
| -------- | --------- | --------------- |
| `<none>` | `uint256` | The proposal ID |

### executeProposal

Executes a proposal that succeeded.

*The caller is not access controlled. However, the proposal must have succeeded and cannot have been executed To succeed, the proposal's for-votes must have reached the quorum and must exceed its against votes. Unless the proposal, has a super-majority, which is 75% in this case, of the votes, it will only be executable once the votiing period has passed. The params and actions are re-validated. The 'target' will also be the treasury*

```solidity
function executeProposal(address shareClass, bytes4 action, bytes memory params, bytes32 descriptionHash)
    public
    virtual
    freezable
    returns (uint256);
```

### executeTx

*Same as StartupGovernor's executeTx(...) except with further data validation. Specifically, the management of the treasury's owners and its threshold are disabled. To change these, the proposal process is required.*

```solidity
function executeTx(address target, uint256 value, bytes memory data, bytes memory signatures, uint256 deadline)
    public
    virtual
    override(StartupGovernor, IStartupGovernor)
    freezable
    returns (bytes memory);
```

### changeTreasuryThreshold

Changes the Treasury's security threshold. Must be called by the governor, itself.

*Meant to be called via the Share Class Governor's executeTx()*

```solidity
function changeTreasuryThreshold(uint256 newTreasuryThreshold) public virtual onlyMezzGovernance freezable;
```

**Parameters**

| Name                   | Type      | Description                        |
| ---------------------- | --------- | ---------------------------------- |
| `newTreasuryThreshold` | `uint256` | The new threshold for the treasury |

### getVotes

Returns the number of votes for an 'account' given a 'shareClass' and 'timepoint'

```solidity
function getVotes(address account, address shareClass, uint256 timepoint) public view virtual returns (uint256);
```

### \_getVotes

*Non-adjusted for voting weight, since all proposals are separated by share classes*

```solidity
function _getVotes(address account, address shareClass, uint256 timepoint) internal view virtual returns (uint256);
```

### quorum

Returns the nominal quorum for a proposal given a 'shareClass' and 'timepoint'.  The nominal quorum is the minimum number of for-votes that a proposal needs to succeed It is based off the quorum percentage, which is set by governance, itself

```solidity
function quorum(address shareClass, uint256 timepoint) public view virtual returns (uint256);
```

### \_quorum

```solidity
function _quorum(address shareClass, uint256 timepoint) internal view virtual returns (uint256);
```

### proposalThreshold

Returns the nominal proposal threshold given a 'shareClass' The nominal proposal threshold is the minimum number of votes that the sender must have for a proposal to be created It is based off the proposal threshold percentage, which is set by governance, itself

```solidity
function proposalThreshold(address shareClass) public view virtual returns (uint256);
```

### \_proposalThreshold

```solidity
function _proposalThreshold(address shareClass) internal view virtual returns (uint256);
```

### superMajority

Returns the nominal super majority given a 'shareClass' and 'timepoint' A super majority in this context is 75% of the total votes for a share class. It a proposal has >75% of for-votes of the outstanding total votes, it is able to skip the voting period and be executed immediately

```solidity
function superMajority(address shareClass, uint256 timepoint) public view virtual returns (uint256);
```

### \_superMajority

```solidity
function _superMajority(address shareClass, uint256 timepoint) internal view virtual returns (uint256);
```

### \_castVote

*'params' are unused outside of event emission*

```solidity
function _castVote(uint256 proposalId, address account, uint8 support, string memory reason, bytes memory params)
    internal
    virtual
    override
    returns (uint256);
```

### hashProposal

Returns the hash of a proposal given a 'shareClass', 'action', 'params', and 'descriptionHash' All of the aforementioned argumetns can be found via events emitted by the Share Class Governor for existing proposals

```solidity
function hashProposal(address shareClass, bytes4 action, bytes memory params, bytes32 descriptionHash)
    public
    pure
    virtual
    returns (uint256);
```

**Returns**

| Name     | Type      | Description                  |
| -------- | --------- | ---------------------------- |
| `<none>` | `uint256` | The proposal ID as a uint256 |

### proposalSnapshot

Returns a proposal's snapshot, which is the time at which votes are counted. Any votes accumulated past this point are not counted towards the proposal

*The snapshot is set during the proposal's and is the sum of the voting delay and block.timestamp*

```solidity
function proposalSnapshot(uint256 proposalId) public view virtual returns (uint256);
```

**Parameters**

| Name         | Type      | Description            |
| ------------ | --------- | ---------------------- |
| `proposalId` | `uint256` | The ID of the proposal |

**Returns**

| Name     | Type      | Description                                                                    |
| -------- | --------- | ------------------------------------------------------------------------------ |
| `<none>` | `uint256` | The snapshot of the proposal, which is measured in seconds from the Unix epoch |

### proposalDeadline

Returns a proposal's deadline, which is the time at which the proposal can no longer be voted on

*The deadline is set during the proposal's creation and is the sum of the voting delay, voting period, and block.timestamp*

```solidity
function proposalDeadline(uint256 proposalId) public view virtual returns (uint256);
```

**Parameters**

| Name         | Type      | Description            |
| ------------ | --------- | ---------------------- |
| `proposalId` | `uint256` | The ID of the proposal |

**Returns**

| Name     | Type      | Description                                                                    |
| -------- | --------- | ------------------------------------------------------------------------------ |
| `<none>` | `uint256` | The deadline of the proposal, which is measured in seconds from the Unix epoch |

### proposalProposer

Returns the proposer of a proposal

```solidity
function proposalProposer(uint256 proposalId) public view virtual returns (address);
```

**Returns**

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

### proposalShareClass

Returns the share class associated with a proposal

```solidity
function proposalShareClass(uint256 proposalId) public view virtual returns (address);
```

**Parameters**

| Name         | Type      | Description            |
| ------------ | --------- | ---------------------- |
| `proposalId` | `uint256` | The ID of the proposal |

**Returns**

| Name     | Type      | Description                    |
| -------- | --------- | ------------------------------ |
| `<none>` | `address` | The address of the share class |

### allocatedBoardSeats

Returns the total number of allocated board seats across all share classes

*This does not include the board seats that have been set. For example, company Foo can have 5 allocated seats yet only 4 members set*

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

### \_allocatedBoardSeats

```solidity
function _allocatedBoardSeats(address treasuryCache) internal view returns (uint256);
```

### getAllocatedSeatsByShareClass

Returns the number of allocated board seats for a given share class

```solidity
function getAllocatedSeatsByShareClass(address shareClass) public view returns (uint256);
```

### getBoardMembersByShareClass

Returns the board members that have been set by a given share class

```solidity
function getBoardMembersByShareClass(address shareClass) public view returns (address[] memory);
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(StartupGovernor, ProposalGovernor, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(StartupGovernor, ProposalGovernor, ICredentialed) returns (uint256);
```

### COUNTING\_MODE

Returns a URL-encoded sequence of key-value pairs that each describe one aspect of voting

*Mezzanine Proposal Governors use votes in line with Bravo. The quorum also only counts for votes, like in Bravo. Reference: <https://docs.openzeppelin.com/contracts/4.x/api/governance#IGovernor-COUNTING\\_MODE-->*

```solidity
function COUNTING_MODE() public view virtual returns (string memory);
```

**Returns**

| Name     | Type     | Description                                 |
| -------- | -------- | ------------------------------------------- |
| `<none>` | `string` | The URL-encoded sequence of key-value pairs |

### \_updateBoardMembers

*Updates state. Also reconstructs the params for a given proposal such that it includes the Treasury's threshold, if needed*

```solidity
function _updateBoardMembers(address treasuryCache, address shareClass, bytes4 action, bytes memory params)
    internal
    virtual
    returns (bytes memory);
```

**Returns**

| Name     | Type    | Description                                       |
| -------- | ------- | ------------------------------------------------- |
| `<none>` | `bytes` | The calldata for the execution of the transaction |

### \_addOwnerForShareClass

*Adds 'ownerToAdd' to the board members for 'shareClass'*

```solidity
function _addOwnerForShareClass(address shareClass, address ownerToAdd) internal virtual;
```

### \_removeOwnerForShareClass

*Removes 'ownerToRemove' from the board members for 'shareClass'*

```solidity
function _removeOwnerForShareClass(address shareClass, address ownerToRemove) internal virtual;
```

### \_checkInvariants

*Reverts if the Treasury's total number of owners is greater than the allocated number of board seats*

```solidity
function _checkInvariants() internal view virtual;
```

### \_validateShareClass

*Reverts if 'shareClass' is not tracked by 'treasuryCache'*

```solidity
function _validateShareClass(address shareClass, address treasuryCache) internal view virtual;
```

### \_validateAction

*Validates that an action to manage the Treasury's owners. Unlike in TeamLogic's manageOwners(), the params for adding an owner and removing an owner do not include arguments to change the threshold for the treasury. This is to prevent a malicious proposal by a preferred share class that adds or switches an owner and then changes the threshold to 1. This would effectively enable them to control the treasury without the consent of the other signers. The threshold param is reconstructed in \_updateBoardMembers(...) to include the Treasury's current threshold. If the threshold is the same as the number of owners, then the threshold is decreased by 1*

```solidity
function _validateAction(bytes4 action, address shareClass, address treasuryCache, bytes memory params)
    internal
    view
    virtual;
```

### \_encodeStateBitmap

```solidity
function _encodeStateBitmap(IModifiedGovernor.ProposalState proposalState) internal pure virtual returns (bytes32);
```

### \_getTotalVotesAtTimepoint

*Returns the past total votes for the 'shareClass' at timepoint. The voting weight of the shares is ignored*

```solidity
function _getTotalVotesAtTimepoint(address shareClass, uint256 timepoint) internal view virtual returns (uint256);
```

### \_superMajorityReached

*Returns whether or not a super majority has been reached for a given proposal. Only for-votes are counted towards the super majority*

```solidity
function _superMajorityReached(uint256 proposalId) internal view virtual returns (bool);
```

**Returns**

| Name     | Type   | Description                                                                |
| -------- | ------ | -------------------------------------------------------------------------- |
| `<none>` | `bool` | True if the for-votes are greater than the super majority, false otherwise |

### \_quorumReached

*Returns whether or not the quourum has been reached for a given proposal. Only for-votes are counted towards the quorum*

```solidity
function _quorumReached(uint256 proposalId) internal view virtual returns (bool);
```

**Returns**

| Name     | Type   | Description                                                        |
| -------- | ------ | ------------------------------------------------------------------ |
| `<none>` | `bool` | True if the for votes are greater than the quorum, false otherwise |

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(ProposalGovernor, StartupGovernor, IERC165)
    returns (bool);
```

## Structs

### ShareClassGovernorStorage

```solidity
struct ShareClassGovernorStorage {
    mapping(address => EnumerableSet.AddressSet) _boardMembersByShareClass;
    mapping(address => uint256) _numberOfSeatsByShareClass;
    mapping(uint256 => DataTypes.ShareClassProposalCore) _proposals;
}
```


# LateStageGovernor

[Git Source](https://github.com/EntreDevelopers-Lab-Inc/Mezz-Companies/blob/f7a3e84e3dd5bb33c4bd7f77283983f9e8ba20b2/src/core/governance/late-stage/LateStageGovernor.sol)

**Inherits:** ProposalGovernor, ModifiedGovernorUpgradeable, ILateStageGovernor

**Author:** Daniel Yamagata & Naveen Ailawadi

A governance contract that is based off of OpenZeppelin's Governor contract. This contract enables the voting of arbitrary on-chain actions, which are represented as proposals. Only 'for-votes' are counted towards the quorum

*Many of these contract's functions run in O(n), where n is the number of shares that a treasury has.  The maximum number of share classes that a Treasury can have is 15.  This contract used a modified version of GovernorUpgradeable to allow access to the the Governor Upgradeable storage internally This is specifically used in propose() and state() to allow for the board of directors to propose and a proposal with a super majority to instantly be executable, respectively.*

## Functions

### constructor

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

### init

Intializes the Governor's state

```solidity
function init(address initTreasury, bytes memory) external virtual override initializer;
```

**Parameters**

| Name           | Type      | Description                                                   |
| -------------- | --------- | ------------------------------------------------------------- |
| `initTreasury` | `address` | The address of the Treasury that the Governor is in charge of |
| `<none>`       | `bytes`   |                                                               |

### \_\_LateStageGovernor\_init

*The 'params' argument is maintained in case future versions require additional initialization parameters*

```solidity
function __LateStageGovernor_init(address initTreasury, bytes memory) internal virtual onlyInitializing;
```

### propose

Creates a new proposal. Vote starts after the delay specified by votingDelay()

*Overridden propose function to add pausable modifier and enable the treasury to make proposals Reference: <https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/4d9d9073b84f56fe3eea360e5067c6ffd864c43d/contracts/governance/GovernorUpgradeable.sol#L277-L330>*

```solidity
function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description)
    public
    virtual
    override(ModifiedGovernorUpgradeable, ILateStageGovernor)
    freezable
    returns (uint256);
```

**Parameters**

| Name          | Type        | Description                                          |
| ------------- | ----------- | ---------------------------------------------------- |
| `targets`     | `address[]` | Target addresses for proposal calls                  |
| `values`      | `uint256[]` | Blockchain native currency values for proposal calls |
| `calldatas`   | `bytes[]`   | Calldatas for proposal calls                         |
| `description` | `string`    |                                                      |

**Returns**

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `<none>` | `uint256` | The proposal ID for the proposal |

### cancel

Cancels a proposal.  Only callable by the Proposer, the Mezz Hub Owner, or a 'Defender'

```solidity
function cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
    public
    virtual
    override(ModifiedGovernorUpgradeable, ILateStageGovernor)
    returns (uint256);
```

**Parameters**

| Name              | Type        | Description                                          |
| ----------------- | ----------- | ---------------------------------------------------- |
| `targets`         | `address[]` | Target addresses for proposal calls                  |
| `values`          | `uint256[]` | Blockchain native currency values for proposal calls |
| `calldatas`       | `bytes[]`   | Calldatas for proposal calls                         |
| `descriptionHash` | `bytes32`   | Hash of the proposal description                     |

**Returns**

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `<none>` | `uint256` | The proposal ID for the proposal |

### execute

Executes a proposal that succeeded. &#x20;

```solidity
function execute(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
    public
    payable
    virtual
    override(ModifiedGovernorUpgradeable, ILateStageGovernor)
    freezable
    returns (uint256);
```

**Parameters**

| Name              | Type        | Description                                          |
| ----------------- | ----------- | ---------------------------------------------------- |
| `targets`         | `address[]` | Target addresses for proposal calls                  |
| `values`          | `uint256[]` | Blockchain native currency values for proposal calls |
| `calldatas`       | `bytes[]`   | Calldatas for proposal calls                         |
| `descriptionHash` | `bytes32`   | Hash of the proposal description                     |

**Returns**

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `<none>` | `uint256` | The proposal ID for the proposal |

### state

Returns the state of a proposal associated with 'proposalId' as a ProposalState enum

```solidity
function state(uint256 proposalId)
    public
    view
    virtual
    override(ModifiedGovernorUpgradeable, ProposalGovernor, IProposalGovernor)
    returns (ProposalState);
```

### quorum

Changed the following line such that if a super majority is reached before the voting period ends, the proposal is instantly executable. There's no need to check if \_quorumReached() or \_voteSucceeded(), since a super majority will always have more for-votes than a quorum, and a super majority will always more for-votes than against-votes, since it is a majority of the total votes.

*The quorum is not a raw value: it is a percentage of the total votes across all share classes*

```solidity
function quorum(uint256 timepoint)
    public
    view
    virtual
    override(ModifiedGovernorUpgradeable, ILateStageGovernor)
    returns (uint256);
```

**Parameters**

| Name        | Type      | Description                         |
| ----------- | --------- | ----------------------------------- |
| `timepoint` | `uint256` | The timepoint to get the quorum for |

**Returns**

| Name     | Type      | Description |
| -------- | --------- | ----------- |
| `<none>` | `uint256` | The quorum  |

### proposalThreshold

Returns the proposal threshold, which is the minimum number of votes that the sender must have for a proposal to be created

*The proposal threshold is not a raw value: it is a percentage of the total votes across all share classes*

```solidity
function proposalThreshold()
    public
    view
    virtual
    override(ModifiedGovernorUpgradeable, ILateStageGovernor)
    returns (uint256);
```

**Returns**

| Name     | Type      | Description              |
| -------- | --------- | ------------------------ |
| `<none>` | `uint256` | The proposal threxwshold |

### superMajority

Returns the nominal value for a super majority at a 'timepoint', which is the number of for-votes needed to execute a proposal instantaneously during the voting period

```solidity
function superMajority(uint256 timepoint) public view virtual returns (uint256);
```

### proposalSnapshot

Returns a proposal's snapshot, which is the time at which votes are counted. Any votes accumulated past this point are not counted towards the proposal

*The snapshot is set during the proposal's and is the sum of the voting delay and block.timestamp*

```solidity
function proposalSnapshot(uint256 proposalId)
    public
    view
    virtual
    override(ModifiedGovernorUpgradeable, IProposalGovernor)
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description            |
| ------------ | --------- | ---------------------- |
| `proposalId` | `uint256` | The ID of the proposal |

**Returns**

| Name     | Type      | Description                                                                    |
| -------- | --------- | ------------------------------------------------------------------------------ |
| `<none>` | `uint256` | The snapshot of the proposal, which is measured in seconds from the Unix epoch |

### proposalDeadline

Returns a proposal's deadline, which is the time at which the proposal can no longer be voted on

*The deadline is set during the proposal's creation and is the sum of the voting delay, voting period, and block.timestamp*

```solidity
function proposalDeadline(uint256 proposalId)
    public
    view
    virtual
    override(ModifiedGovernorUpgradeable, IProposalGovernor)
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description            |
| ------------ | --------- | ---------------------- |
| `proposalId` | `uint256` | The ID of the proposal |

**Returns**

| Name     | Type      | Description                                                                    |
| -------- | --------- | ------------------------------------------------------------------------------ |
| `<none>` | `uint256` | The deadline of the proposal, which is measured in seconds from the Unix epoch |

### proposalProposer

Returns the proposer of a proposal

```solidity
function proposalProposer(uint256 proposalId)
    public
    view
    virtual
    override(ModifiedGovernorUpgradeable, IProposalGovernor)
    returns (address);
```

**Returns**

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

### votingDelay

Returns the voting delay in seconds

```solidity
function votingDelay()
    public
    view
    virtual
    override(ProposalGovernor, IProposalGovernor, ModifiedGovernorUpgradeable)
    returns (uint256);
```

**Returns**

| Name     | Type      | Description                 |
| -------- | --------- | --------------------------- |
| `<none>` | `uint256` | The voting delay in seconds |

### votingPeriod

Returns the voting period

```solidity
function votingPeriod()
    public
    view
    virtual
    override(ProposalGovernor, IProposalGovernor, ModifiedGovernorUpgradeable)
    returns (uint256);
```

**Returns**

| Name     | Type      | Description                  |
| -------- | --------- | ---------------------------- |
| `<none>` | `uint256` | The voting period in seconds |

### hasVoted

Returns true if 'account' has voted on a proposal with 'proposalId', false otherwise

```solidity
function hasVoted(uint256 proposalId, address account)
    public
    view
    virtual
    override(ProposalGovernor, IProposalGovernor, IModifiedGovernor)
    returns (bool);
```

**Returns**

| Name     | Type   | Description                                    |
| -------- | ------ | ---------------------------------------------- |
| `<none>` | `bool` | True if the account has voted, false otherwise |

### clock

*EIP-6372 support*

```solidity
function clock()
    public
    view
    virtual
    override(ProposalGovernor, ModifiedGovernorUpgradeable, IERC6372)
    returns (uint48);
```

### CLOCK\_MODE

*EIP-6372 support*

```solidity
function CLOCK_MODE()
    public
    view
    virtual
    override(ProposalGovernor, ModifiedGovernorUpgradeable, IERC6372)
    returns (string memory);
```

### COUNTING\_MODE

Returns a URL-encoded sequence of key-value pairs that each describe one aspect of voting

*Mezzanine Proposal Governors use votes in line with Bravo. The quorum also only counts for votes, like in Bravo. Reference: <https://docs.openzeppelin.com/contracts/4.x/api/governance#IGovernor-COUNTING\\_MODE-->*

```solidity
function COUNTING_MODE() public view virtual override(IModifiedGovernor, IProposalGovernor) returns (string memory);
```

**Returns**

| Name     | Type     | Description                                 |
| -------- | -------- | ------------------------------------------- |
| `<none>` | `string` | The URL-encoded sequence of key-value pairs |

### name

Returns the name of the governor

```solidity
function name() public view virtual override(ModifiedGovernorUpgradeable, MezzGovernor) returns (string memory);
```

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(ProposalGovernor, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version()
    public
    pure
    virtual
    override(ModifiedGovernorUpgradeable, ProposalGovernor, ICredentialed)
    returns (uint256);
```

### castVote

Casts the caller's votes towards the proposal associated with 'proposalId' There are three different vote types defined by the following enum:

* 0: Against
* 1: For
* 2: Abstain

*A voter can only vote once and cannot revoke or change their vote. Votes are calculated from the proposal's snapshot and the counting of votes is bespoke and must be implemented by the inheritor*

```solidity
function castVote(uint256 proposalId, uint8 support)
    public
    virtual
    override(ModifiedGovernorUpgradeable, ProposalGovernor, IProposalGovernor)
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `proposalId` | `uint256` | The ID of the proposal to cast the vote for |
| `support`    | `uint8`   | The vote type                               |

**Returns**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `<none>` | `uint256` | The number of votes of the caller |

### castVoteWithReason

Casts the caller's votes with a 'reason' towards the proposal associated with 'proposalId'

*The 'reason' is not stored on-chain but, rather, emitted in an event*

```solidity
function castVoteWithReason(uint256 proposalId, uint8 support, string calldata reason)
    public
    virtual
    override(ModifiedGovernorUpgradeable, ProposalGovernor, IProposalGovernor)
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `proposalId` | `uint256` | The ID of the proposal to cast the vote for |
| `support`    | `uint8`   | The vote type                               |
| `reason`     | `string`  | The reason for the vote                     |

**Returns**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `<none>` | `uint256` | The number of votes of the caller |

### castVoteWithReasonAndParams

Casts the caller's votes with a 'reason' and 'params' towards the proposal associated with 'proposalId'

*'params' are bespoke, abi-encoded arguments that could be used for casting a vote*

```solidity
function castVoteWithReasonAndParams(uint256 proposalId, uint8 support, string calldata reason, bytes memory params)
    public
    virtual
    override(ModifiedGovernorUpgradeable, ProposalGovernor, IProposalGovernor)
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `proposalId` | `uint256` | The ID of the proposal to cast the vote for |
| `support`    | `uint8`   | The vote type                               |
| `reason`     | `string`  | The reason for the vote                     |
| `params`     | `bytes`   | The abi-encoded parameters for the vote     |

**Returns**

| Name     | Type      | Description                       |
| -------- | --------- | --------------------------------- |
| `<none>` | `uint256` | The number of votes of the caller |

### castVoteBySig

Casts the votes of 'voter' towards the proposal associated with 'proposalId' via an EIP-712 signature

*Reference: <https://eips.ethereum.org/EIPS/eip-712>*

```solidity
function castVoteBySig(uint256 proposalId, uint8 support, address voter, bytes memory signature)
    public
    virtual
    override(ModifiedGovernorUpgradeable, ProposalGovernor, IProposalGovernor)
    returns (uint256);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `proposalId` | `uint256` | The ID of the proposal to cast the vote for |
| `support`    | `uint8`   | The vote type                               |
| `voter`      | `address` | The address of the voter                    |
| `signature`  | `bytes`   | The EIP-712 signature of the voter          |

**Returns**

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `<none>` | `uint256` | The number of votes of the voter |

### castVoteWithReasonAndParamsBySig

Casts the votes of 'voter' towards the proposal associated with 'proposalId' via an EIP-712 signature

*Reference: <https://eips.ethereum.org/EIPS/eip-712> 'params' are bespoke, abi-encoded arguments that could be used for casting a vote*

```solidity
function castVoteWithReasonAndParamsBySig(
    uint256 proposalId,
    uint8 support,
    address voter,
    string calldata reason,
    bytes memory params,
    bytes memory signature
) public virtual override(ModifiedGovernorUpgradeable, ProposalGovernor, IProposalGovernor) returns (uint256);
```

**Parameters**

| Name         | Type      | Description                                 |
| ------------ | --------- | ------------------------------------------- |
| `proposalId` | `uint256` | The ID of the proposal to cast the vote for |
| `support`    | `uint8`   | The vote type                               |
| `voter`      | `address` | The address of the voter                    |
| `reason`     | `string`  | The reason for the vote                     |
| `params`     | `bytes`   | The abi-encoded parameters for the vote     |
| `signature`  | `bytes`   | The EIP-712 signature of the voter          |

**Returns**

| Name     | Type      | Description                      |
| -------- | --------- | -------------------------------- |
| `<none>` | `uint256` | The number of votes of the voter |

### \_castVote

```solidity
function _castVote(uint256 proposalId, address account, uint8 support, string memory reason)
    internal
    virtual
    override(ProposalGovernor, ModifiedGovernorUpgradeable)
    returns (uint256);
```

### \_castVote

*OZ's GovernorUpgradeable vote casting is used directly here*

```solidity
function _castVote(uint256 proposalId, address account, uint8 support, string memory reason, bytes memory params)
    internal
    virtual
    override(ProposalGovernor, ModifiedGovernorUpgradeable)
    returns (uint256);
```

### \_countVote

*Counts a vote for a given proposal. Sets the receipt in storage. Assumes that weight has already been calculated*

```solidity
function _countVote(uint256 proposalId, address account, uint8 support, uint256 votes, bytes memory)
    internal
    virtual
    override(ModifiedGovernorUpgradeable, ProposalGovernor);
```

### \_getTotalVotesAtTimepoint

*Queries all the shares and returns the summation of the total votes at the given timepoint*

```solidity
function _getTotalVotesAtTimepoint(uint256 timepoint) internal view returns (uint256);
```

### \_getVotes

*Queries all the shares and returns the summation of the votes for the account at the given timepoint*

```solidity
function _getVotes(address account, uint256 timepoint, bytes memory) internal view virtual override returns (uint256);
```

### \_superMajorityReached

*Returns whether or not a super majority has been reached for a given proposal. Only for-votes are counted towards the super majority*

```solidity
function _superMajorityReached(uint256 proposalId) internal view virtual returns (bool);
```

**Returns**

| Name     | Type   | Description                                                                |
| -------- | ------ | -------------------------------------------------------------------------- |
| `<none>` | `bool` | True if the for-votes are greater than the super majority, false otherwise |

### \_quorumReached

*Returns whether or not the quourum has been reached for a given proposal. Only for-votes are counted towards the quorum*

```solidity
function _quorumReached(uint256 proposalId) internal view override returns (bool);
```

**Returns**

| Name     | Type   | Description                                                        |
| -------- | ------ | ------------------------------------------------------------------ |
| `<none>` | `bool` | True if the for votes are greater than the quorum, false otherwise |

### \_voteSucceeded

*Returns whether or not the vote succeeded for a given proposal*

```solidity
function _voteSucceeded(uint256 proposalId)
    internal
    view
    override(ModifiedGovernorUpgradeable, ProposalGovernor)
    returns (bool);
```

**Returns**

| Name     | Type   | Description                                                               |
| -------- | ------ | ------------------------------------------------------------------------- |
| `<none>` | `bool` | True if the for votes are greater than the against votes, false otherwise |

### eip712Domain

*EIP-5267 support. Reference: <https://eips.ethereum.org/EIPS/eip-5267>*

```solidity
function eip712Domain()
    public
    view
    virtual
    override(EIP712Upgradeable, IERC5267, MezzEIP712)
    returns (
        bytes1 fields,
        string memory __name,
        string memory __version,
        uint256 chainId,
        address verifyingContract,
        bytes32 salt,
        uint256[] memory extensions
    );
```

### supportsInterface

*EIP-165 support. Reference: <https://eips.ethereum.org/EIPS/eip-165>*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(ModifiedGovernorUpgradeable, ProposalGovernor, IERC165)
    returns (bool);
```


# MezzGuard

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

**Inherits:** BaseGuard, Initializable, Credentialed, CommonValidation, IMezzGuard

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

A base contract inherited by guards used in Mezzanine. A 'Guard' refers to [Safe Guards](https://github.com/safe-global/safe-contracts/blob/82dfcc8c0cf21c0f76db354d691d668093fe1618/contracts/base/GuardManager.sol).&#x20;

*Mezzanine guards are set up such that adding, swapping, or removing owners, setting a guard, or enabling a module is disabled via the multi-signature funcitonality of the 'controlled'. Instead, particular functions in departments and the treasury must be used to access these functions. Specifically, access control is managed such that only an 'ancestor' or governance can call these functions*

## State Variables

### MezzGuardStorageLocation

```solidity
bytes32 private constant MezzGuardStorageLocation = 0xe3d6cd3491c5540f279d53d4dae5705fec2cdb498a14a972c3514ce2c3f77200;
```

## Functions

### \_getMezzGuardStorage

```solidity
function _getMezzGuardStorage() internal pure returns (MezzGuardStorage storage $);
```

### constructor

```solidity
constructor();
```

### onlyController

```solidity
modifier onlyController();
```

### init

Initializes the Mezz Guard's state. Sets the defaults from the deployer

*Mezz Guards are initialized atomically as they are deployed*

```solidity
function init(
    address initControlled,
    address initController,
    address[] calldata contractListDefaults,
    DataTypes.GuardSelector[] calldata selectorListDefaults,
    bytes memory
) external virtual initializer;
```

**Parameters**

| Name                   | Type                        | Description                                       |
| ---------------------- | --------------------------- | ------------------------------------------------- |
| `initControlled`       | `address`                   |                                                   |
| `initController`       | `address`                   |                                                   |
| `contractListDefaults` | `address[]`                 | The default contracts to add to the contract list |
| `selectorListDefaults` | `DataTypes.GuardSelector[]` | The default selectors to add to the selector list |
| `<none>`               | `bytes`                     |                                                   |

### \_\_MezzGuard\_init

*Initializes the Mezz Guard's state. Sets the defaults from the deployer*

```solidity
function __MezzGuard_init(
    address initControlled,
    address initController,
    address[] memory contractListDefaults,
    DataTypes.GuardSelector[] memory selectorListDefaults
) internal;
```

### addSelectorToList

Adds a guard selector to the selector list, which will either enable or disable the function to be called by 'controlled'. A guard selector is made up of an address and a function selector

```solidity
function addSelectorToList(DataTypes.GuardSelector memory selectorToAdd) external onlyController;
```

**Parameters**

| Name            | Type                      | Description                                                             |
| --------------- | ------------------------- | ----------------------------------------------------------------------- |
| `selectorToAdd` | `DataTypes.GuardSelector` | The contract address and function selector pair to be added to the list |

### \_addSelectorToList

*Adds the selector to the list. Updates the index for the selector. Reverts if the selector is already on the list*

```solidity
function _addSelectorToList(DataTypes.GuardSelector memory selectorToAdd) internal virtual;
```

### removeSelectorFromList

Removes a guard selector from the selector list, which will either enable or disable the function to be called by 'controlled'. A guard selector is made up of an address and a function selector.

```solidity
function removeSelectorFromList(DataTypes.GuardSelector memory selectorToRemove) external onlyController;
```

**Parameters**

| Name               | Type                      | Description                                                               |
| ------------------ | ------------------------- | ------------------------------------------------------------------------- |
| `selectorToRemove` | `DataTypes.GuardSelector` | A contract address and function selector pair to be removed from the list |

### addContractToList

Adds a contract to the contract list, which will either enable or disable the function to be called by 'controlled'

```solidity
function addContractToList(address contractToAdd) external onlyController;
```

### \_addContractToList

*Adds the contract to the list. Reverts if the contract is already on the list*

```solidity
function _addContractToList(address contractToAdd) internal virtual;
```

### removeContractFromList

Removes a contract from the contract list. Any contract removed from the list will be either enabled or disabled for the 'controlled' to interact with depending on whether the guard is a whitelist or blacklist guard, respectively. This is true no matter the function selector

```solidity
function removeContractFromList(address contractToRemove) external onlyController;
```

### onList

Returns true if '\_to' or the function selector of '\_data' for '\_to' is on either the contract list or selector list. Otherwise, returns false.

```solidity
function onList(address _to, bytes memory _data) public view virtual returns (bool);
```

### checkAfterExecution

*Called by a Safe after the execution of a transaction. Reverts if the transaction failed*&#x20;

*Reference: <https://github.com/safe-global/safe-smart-account/blob/f03dfae65fd1d085224b00a10755c509a4eaacfe/contracts/Safe.sol#L215-L217>*

```solidity
function checkAfterExecution(bytes32, bool success) external pure virtual;
```

### checkModuleTransaction

*Safe modules are always disabled in the initial version of Mezzanine*

```solidity
function checkModuleTransaction(address, uint256, bytes memory, Enum.Operation, address)
    external
    pure
    returns (bytes32);
```

### getSelectorList

Returns the selectors list which may either be whitelisted or blacklisted depending on the guard

```solidity
function getSelectorList() external view returns (DataTypes.GuardSelector[] memory);
```

### getContractList

Returns the contracts list which may be either whitelisted or blacklisted depending on the guard

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

### getControlled

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

**Returns**

| Name     | Type      | Description                                                        |
| -------- | --------- | ------------------------------------------------------------------ |
| `<none>` | `address` | The controlled, which is a team whose guard is likely to be 'this' |

### getController

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

**Returns**

| Name     | Type      | Description                                                                                                                                         |
| -------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `address` | The address which has admin control over the guard. The 'controller' can add or remove functions on both the '\_selectorList' and '\_contractList'. |

### coreId

Returns the coreId of the implementation as a bytes32

*The core ID is the keccak256 hash of the contract name followed by a version under the following syntax: "mezzanine.coreId.ContractName.vX" For example, the core ID of the 2nd version of the Treasury would be the following: keccak256(abi.encodePacked("mezzanine.coreId.Treasury.v2"))*

```solidity
function coreId() public pure virtual override(Credentialed, ICredentialed) returns (bytes32);
```

### version

Returns the version of the implementation as a uint256

```solidity
function version() public pure virtual override(Credentialed, ICredentialed) returns (uint256);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(BaseGuard, Credentialed, IMezzGuard)
    returns (bool);
```

### \_checkTransaction

\*Reverts under the following scenarios:

* The '\_operation' is a delegate call
* The '\_data' is an add owner, remove owner, or swap owner on the msg.sender
* The '\_data' is a set guard
* The '\_data' is to enable a module\*

```solidity
function _checkTransaction(address to, bytes memory data, Enum.Operation operation) internal view virtual;
```

### \_onSelectorList

*Returns true if the index of '\_listInfo' is not 0, false otherwise*

```solidity
function _onSelectorList(DataTypes.GuardSelector memory _listInfo) internal view virtual returns (bool);
```

### \_onContractList

*Returns true if the '\_to' is on the '\_contractList', false otherwise*

```solidity
function _onContractList(address _to) internal view virtual returns (bool);
```

### \_validateCallerIsController

*Validates that the caller is '\_\_controller();*

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

### \_\_controller

*Returns the '\_controller'. Can be overridden to return an arbitrary address*

```solidity
function __controller() internal view virtual returns (address);
```

## Structs

### MezzGuardStorage

```solidity
struct MezzGuardStorage {
    address _controlled;
    address _controller;
    EnumerableSet.AddressSet _contractList;
    DataTypes.GuardSelector[] _selectorList;
    mapping(address => mapping(bytes4 => uint256)) _selectorIndexes;
}
```


# BlacklistGuard

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

**Inherits:** MezzGuard

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

A Mezzanine guard that is capable of blacklisting operations that a team can execute. Blacklisted operations are determined by a 'controller', which is typically the Team's parent

\*Operations are blacklisted based on two sets:

* A set of blacklisted contracts
* A set of blacklisted selectors, which are each associated with a contract. For example, if ERC20 contract 'Foo' is part of the contract set, all functions associated with it will be disabled. Similarly, if the function selector of 'bar()' is part of the blacklisted selectors for 'Foo', all calls to 'bar()' by the team will be disabled

## Functions

### checkTransaction

Reverts if 'to' or the function selector of 'data' for 'to' is blacklisted. Will also revert if the operation is a delegate call or relates to the management of the owners, modules, or guard of the 'controlled' Reference: <https://github.com/safe-global/safe-smart-account/blob/f03dfae65fd1d085224b00a10755c509a4eaacfe/contracts/Safe.sol#L173-L190>

```solidity
function checkTransaction(
    address to,
    uint256,
    bytes memory data,
    Enum.Operation operation,
    uint256,
    uint256,
    uint256,
    address,
    address payable,
    bytes memory,
    address
) external view virtual;
```

### coreId

```solidity
function coreId() public pure virtual override returns (bytes32);
```

### version

```solidity
function version() public pure virtual override returns (uint256);
```


# WhitelistGuard

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

**Inherits:** MezzGuard

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

A Mezzanine guard that is capable of whitelisting operations that a team can execute. All non-whitelisted operations will revert. Whitelisted operations are determined by a 'controller', which is typically the parent of the 'controlled'

\*Operations are whitelisted based on two sets:

* A set of whitelisted contracts
* A set of whitelisted selectors, which are each associated with a contract For example, if ERC20 contract 'Foo' is part of the contract set, all functions associated with it will be enabled. Similarly, if the function selector of 'bar()' is part of the whitelisted selectors for 'Foo', all calls to 'bar()' by the team will be enabled

## Functions

### checkTransaction

Reverts if 'to' or the function selector of 'data' for 'to' is not whitelisted. Will also revert if the operation is a delegate call or relates to the management of the owners, modules, or guard of the 'controlled' Reference: <https://github.com/safe-global/safe-smart-account/blob/f03dfae65fd1d085224b00a10755c509a4eaacfe/contracts/Safe.sol#L173-L190>

```solidity
function checkTransaction(
    address to,
    uint256,
    bytes memory data,
    Enum.Operation operation,
    uint256,
    uint256,
    uint256,
    address,
    address payable,
    bytes memory,
    address
) external view virtual;
```

### coreId

```solidity
function coreId() public pure virtual override returns (bytes32);
```

### version

```solidity
function version() public pure virtual override returns (uint256);
```


# ShareholderGuard

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

**Inherits:** BlacklistGuard

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

A blacklist guard whose 'controller' is the 'governor' of the company of the 'controlled'.

## Functions

### coreId

```solidity
function coreId() public pure virtual override returns (bytes32);
```

### version

```solidity
function version() public pure virtual override returns (uint256);
```

### \_\_controller

*Overridden \_\_controller() such that it returns the controlled's governor*

```solidity
function __controller() internal view virtual override returns (address);
```


# 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;
}
```


# 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;
}
```


# MezzMigrator

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

**Inherits:** ReentrancyGuardUpgradeable, HubOwnableUUPSUpgradeable, IMezzMigrator

**Author:** Daniel Yamagata & Naveen Ailawadi

The Mezz Migrator is responsible for upgrading core contracts to newer versions, resetting the latest versions to patched implementations, and providing the address of the latest version of an implementation

*The data used for a reinitialization function is validated such that a team cannot manage its owners, modules, or guard during an upgrade*

## State Variables

### MezzMigratorStorageLocation

```solidity
bytes32 private constant MezzMigratorStorageLocation =
    0x14b40c2177fe6203daba99a4176ffdb237b2208d924b24ad9173fc87b13b6a00;
```

## Functions

### \_getMezzMigratorStorage

```solidity
function _getMezzMigratorStorage() internal pure returns (MezzMigratorStorage storage $);
```

### constructor

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

### init

Initializer for the Mezz Migrator. Sets up the V1 implementations for the given Core IDs. Only callabe by the owner of the Mezz Hub

*Even though Mezz Migrator is not UUPSUpgradeable, an initializer is used to set up the V1 implementations This is due to the fact that implementations need to be aware of the Mezz Migrator upon construction Therefore, the Mezz Migrator is unable to use them in its own construction*

```solidity
function init(bytes32[] memory coreIds, address[] memory implementations) external initializer onlyHubOwner;
```

**Parameters**

| Name              | Type        | Description                          |
| ----------------- | ----------- | ------------------------------------ |
| `coreIds`         | `bytes32[]` | The coreIds of the implementations   |
| `implementations` | `address[]` | The addresses of the implementations |

### \_\_MezzMigrator\_init

```solidity
function __MezzMigrator_init(bytes32[] memory coreIds, address[] memory implementations) internal onlyInitializing;
```

### setNewCoreVersion

Sets a 'newImplementation' for the latest version of 'coreId'. Only callable by the Mezz Hub Owner

```solidity
function setNewCoreVersion(bytes32 coreId, address newImplementation) external onlyHubOwner;
```

**Parameters**

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

### resetLatestCoreVersion

Resets the latest version associated with the Core ID back to the prior version. Only callable by the Mezz Hub Owner

*Does not change the latest core version. Only resets the latest version's implementation for a given core ID*

```solidity
function resetLatestCoreVersion(bytes32 coreId, address newImplementation) external onlyHubOwner;
```

**Parameters**

| Name                | Type      | Description                                         |
| ------------------- | --------- | --------------------------------------------------- |
| `coreId`            | `bytes32` | The core ID to reset the latest version for         |
| `newImplementation` | `address` | The new implementation to set the latest version to |

### upgradeToNewerVersion

Upgrades the caller, who is assumed to be a contract, to a newer version

*This function is not access controlled*

```solidity
function upgradeToNewerVersion(uint256 newVersion, bytes memory data) external pausable nonReentrant;
```

### resetToPatchedLatestVersion

Resets the caller's contract to the latest version, which should be patched beforehand. Only callabe if the protocol state is paused or frozen

*The caller must be the latest version to be able to reset the latest patched version*

```solidity
function resetToPatchedLatestVersion(bytes memory data) external nonReentrant;
```

**Parameters**

| Name   | Type    | Description                      |
| ------ | ------- | -------------------------------- |
| `data` | `bytes` | Data used for the initialization |

### getLatestVersion

Returns the latest version for a given core implementation

```solidity
function getLatestVersion(bytes32 coreId) external view returns (uint256);
```

**Returns**

| Name     | Type      | Description                     |
| -------- | --------- | ------------------------------- |
| `<none>` | `uint256` | The latest version as a uint256 |

### getLatestCoreImplementation

Returns the latest implementation for a given core ID

```solidity
function getLatestCoreImplementation(bytes32 coreId) external view returns (address);
```

### getCoreImplementationByVersion

Returns the implementation for a given core ID and version

```solidity
function getCoreImplementationByVersion(bytes32 coreId, uint256 version) external view returns (address);
```

### \_setUpV1CoreIds

*Validates and sets the initial core IDs and implementations in the constructor*

```solidity
function _setUpV1CoreIds(bytes32[] memory coreIds, address[] memory implementations) internal;
```

### \_validateImplementationSupportsCredentialedInterface

*Validates that the implementation supports the 'ICredentialed' interface*

```solidity
function _validateImplementationSupportsCredentialedInterface(address implementation) internal view;
```

### \_validateLatestVersion

*Reverts if the latest version is zero*

```solidity
function _validateLatestVersion(uint256 latestVersion, bytes32 coreId) internal pure;
```

### \_validateVersion

*Reverts if 'version is zero or greater than 'latestVersion'*

```solidity
function _validateVersion(uint256 version, uint256 latestVersion) internal pure;
```

### \_validateImplementationVersion

*Validates that the implementation version is equal to the 'expectedVersion'*

```solidity
function _validateImplementationVersion(uint256 expectedVersion, address implementation) internal pure;
```

### \_validateImplementationCoreId

*Validates that the implementation core ID is equal to the passed in core ID*

```solidity
function _validateImplementationCoreId(bytes32 coreId, address implementation) internal pure;
```

## Structs

### MezzMigratorStorage

```solidity
struct MezzMigratorStorage {
    mapping(bytes32 => mapping(uint256 => address)) _implementationByCoreIdByVersion;
    mapping(bytes32 => uint256) _implementationVersion;
}
```


# BillingRouter

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

**Inherits:** Initializable, ContextUpgradeable, HubOwnableUUPSUpgradeable, ERC165Upgradeable, IBillingRouter

**Author:** Daniel Yamagata & Jerry Qi

A contract for sending and paying invoices

*This contract uses ContextUpgradeable to allow for future versions to use a gas relayer if desired*

## State Variables

### BillingRouterStorageLocation

```solidity
bytes32 private constant BillingRouterStorageLocation =
    0x37f3f3ea6bd3134a12f955ddfd4147e5790b22caaa1c2898646a2bd9d6b60b00;
```

## Functions

### \_getBillingRouterStorage

```solidity
function _getBillingRouterStorage() internal pure returns (BillingRouterStorage storage $);
```

### onlyVendor

*Reverts if the caller is not the vendor of 'invoiceId' or if the invoice does not exist*

```solidity
modifier onlyVendor(bytes32 invoiceId);
```

### constructor

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

### sendInvoice

Sends an invoice to a billable party. Returns the invoice ID

*Anyone can pay the invoice on behalf of the billable party*

```solidity
function sendInvoice(
    address billableParty,
    address denominationAsset,
    uint256 amount,
    uint256 dueDate,
    bytes32 categoryId,
    string memory description,
    string memory documentName,
    string memory documentUri
) external virtual pausable returns (bytes32);
```

**Parameters**

| Name                | Type      | Description                                                                                                                                                                          |
| ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `billableParty`     | `address` | The address of the billable party                                                                                                                                                    |
| `denominationAsset` | `address` | The address of the denomination asset used for the invoice                                                                                                                           |
| `amount`            | `uint256` | The amount of the denomination asset to be paid                                                                                                                                      |
| `dueDate`           | `uint256` | The due date of the invoice. Must be in the future                                                                                                                                   |
| `categoryId`        | `bytes32` | The category ID of the invoice. Should be the keccak256 hash of the category name. For example, the category ID of "Transportation Services" is keccak256("Transportation Services") |
| `description`       | `string`  | The description of the invoice                                                                                                                                                       |
| `documentName`      | `string`  | The name of the document associated with the invoice                                                                                                                                 |
| `documentUri`       | `string`  | The URI of the document associated with the invoice                                                                                                                                  |

**Returns**

| Name     | Type      | Description           |
| -------- | --------- | --------------------- |
| `<none>` | `bytes32` | The ID of the invoice |

### payInvoice

Pays the invoice with 'invoiceId'

*The amount paid to the vendor may be different from the amount specified in the invoice. This is due to some ERC20s having fees built into the transfer function of ERC20s.*

```solidity
function payInvoice(bytes32 invoiceId) external virtual freezable returns (uint256);
```

**Parameters**

| Name        | Type      | Description                      |
| ----------- | --------- | -------------------------------- |
| `invoiceId` | `bytes32` | The ID of the invoice to be paid |

**Returns**

| Name     | Type      | Description                                             |
| -------- | --------- | ------------------------------------------------------- |
| `<none>` | `uint256` | The amount of the denomination asset paid to the vendor |

### cancelInvoice

Cancels the invoice with 'invoiceId'

*Can only be called by the invoice's vendor*

```solidity
function cancelInvoice(bytes32 invoiceId) external virtual onlyVendor(invoiceId) pausable;
```

**Parameters**

| Name        | Type      | Description                           |
| ----------- | --------- | ------------------------------------- |
| `invoiceId` | `bytes32` | The ID of the invoice to be cancelled |

### updateInvoiceDocument

Updates the document related to the invoice with 'invoiceId' in the Document Registry

*Can only be called by the invoice's vendor*

```solidity
function updateInvoiceDocument(bytes32 invoiceId, string memory updatedDocumentName, string memory updatedDocumentUri)
    external
    virtual
    onlyVendor(invoiceId)
    returns (uint256);
```

**Parameters**

| Name                  | Type      | Description                                           |
| --------------------- | --------- | ----------------------------------------------------- |
| `invoiceId`           | `bytes32` | The ID of the invoice whose document is to be updated |
| `updatedDocumentName` | `string`  | The updated name of the document                      |
| `updatedDocumentUri`  | `string`  | The updated URI of the document                       |

**Returns**

| Name     | Type      | Description                     |
| -------- | --------- | ------------------------------- |
| `<none>` | `uint256` | The new version of the document |

### hashInvoice

Returns the ID of an invoice given the invoice's parameters

*The description hash can be queried via event emission*

```solidity
function hashInvoice(
    address vendor,
    address billableParty,
    address denominationAsset,
    uint256 amount,
    uint256 dueDate,
    bytes32 categoryId,
    bytes32 descriptionHash
) public pure returns (bytes32);
```

### isInvoicePaid

Returns true if the invoice with 'invoiceId' has been paid, false otherwise

```solidity
function isInvoicePaid(bytes32 invoiceId) external view returns (bool);
```

### isInvoicePastDue

Returns true if the invoice with 'invoiceId' is past due, false otherwise

```solidity
function isInvoicePastDue(bytes32 invoiceId) external view returns (bool);
```

### getInvoiceById

Returns the invoice with 'invoiceId' as a DataTypes.Invoice struct

```solidity
function getInvoiceById(bytes32 invoiceId) external view returns (DataTypes.Invoice memory);
```

### \_validateDenominationAsset

*Reverts if 'denominationAsset' is invalid*

```solidity
function _validateDenominationAsset(address denominationAsset) internal view virtual;
```

### \_validateCallerIsVendor

```solidity
function _validateCallerIsVendor(bytes32 invoiceId) internal view virtual;
```

### \_validateInvoiceExists

```solidity
function _validateInvoiceExists(bytes32 invoiceId) internal view virtual;
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(ERC165Upgradeable, IERC165)
    returns (bool);
```

## Structs

### BillingRouterStorage

```solidity
struct BillingRouterStorage {
    mapping(bytes32 => DataTypes.Invoice) _invoiceById;
}
```


# DocumentRegistry

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

**Inherits:** ContextUpgradeable, HubOwnableUUPSUpgradeable, IDocumentRegistry

**Author:** Daniel Yamagata & Jerry Qi

A registry that keeps track of documents for departments and treasuries

*ContextUpgradeable's \_msgSender() is used instead of msg.sender to support gas relayers in the future if needed Document indices and versions are indexed at zero*

## State Variables

### DocumentRegistryStorageLocation

```solidity
bytes32 private constant DocumentRegistryStorageLocation =
    0x46700f930ad7adfc0a292e81ee80058e1cf74d898e6dd683beb9ef96db973800;
```

## Functions

### \_getDocumentRegistryStorage

```solidity
function _getDocumentRegistryStorage() internal pure returns (DocumentRegistryStorage storage $);
```

### constructor

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

### addDocument

Adds a document to the registry for the caller

*This function is not access controlled: any account can add a document to the registry if desired*

```solidity
function addDocument(string memory documentName, string memory documentUri) external virtual returns (uint256);
```

**Returns**

| Name     | Type      | Description                                                          |
| -------- | --------- | -------------------------------------------------------------------- |
| `<none>` | `uint256` | The document index, which is incremented sequentially for the caller |

### updateDocument

Updates the document associated with 'documentIndex' in the registry for the caller

*This function will revert if the 'documentIndex' is invalid*

```solidity
function updateDocument(uint256 documentIndex, string memory updatedDocumentName, string memory updatedDocumentUri)
    external
    virtual
    returns (uint256);
```

**Parameters**

| Name                  | Type      | Description                         |
| --------------------- | --------- | ----------------------------------- |
| `documentIndex`       | `uint256` | The index of the document to update |
| `updatedDocumentName` | `string`  | The updated name of the document    |
| `updatedDocumentUri`  | `string`  | The updated URI of the document     |

**Returns**

| Name     | Type      | Description                                                                     |
| -------- | --------- | ------------------------------------------------------------------------------- |
| `<none>` | `uint256` | The version of the document, which is incremented sequentially upon each update |

### getLatestDocuments

Returns all of the latest documents associated with an 'owner'

```solidity
function getLatestDocuments(address owner) public view virtual returns (DataTypes.Document[] memory);
```

**Parameters**

| Name    | Type      | Description                |
| ------- | --------- | -------------------------- |
| `owner` | `address` | The owner of the documents |

**Returns**

| Name     | Type                   | Description                                         |
| -------- | ---------------------- | --------------------------------------------------- |
| `<none>` | `DataTypes.Document[]` | A list of documents as a 'DataTypes.Document' array |

### getLatestDocumentByIndex

Returns the latest document given an 'owner' and 'documentIndex'

```solidity
function getLatestDocumentByIndex(address owner, uint256 documentIndex)
    public
    view
    virtual
    returns (DataTypes.Document memory);
```

### getDocumentByVersion

Returns a document given an 'owner', 'documentIndex', and 'documentVersion'

*This function will revert if the document does not exist*

```solidity
function getDocumentByVersion(address owner, uint256 documentIndex, uint256 documentVersion)
    public
    view
    virtual
    returns (DataTypes.Document memory);
```

**Parameters**

| Name              | Type      | Description                 |
| ----------------- | --------- | --------------------------- |
| `owner`           | `address` | The owner of the document   |
| `documentIndex`   | `uint256` | The index of the document   |
| `documentVersion` | `uint256` | The version of the document |

**Returns**

| Name     | Type                 | Description                                   |
| -------- | -------------------- | --------------------------------------------- |
| `<none>` | `DataTypes.Document` | The document as a 'DataTypes.Document' struct |

### \_validateDocumentExistence

*Validates that the document exists, reverts if it does not*

```solidity
function _validateDocumentExistence(address owner, uint256 documentIndex) internal view;
```

## Structs

### DocumentRegistryStorage

```solidity
struct DocumentRegistryStorage {
    mapping(address => mapping(uint256 => DataTypes.VersionedDocuments)) _documentByOwnerByIndex;
    mapping(address => uint256) _nextDocumentIndexByOwner;
}
```


# FeeController

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

**Inherits:** Initializable, ERC165Upgradeable, HubOwnableUUPSUpgradeable, IFeeController

**Author:** Daniel Yamagata & Naveen Ailawadi

A contract to set and manage fees for the Mezzanine Protocol

*All fees are denominated in 100\_000 as 100%. For example, a fee of 1\_000 is equivalent to 1% All fees in Mezzanine are transferred to the fee controller, which then can be collected by the owner of the Mezz Hub. All implementations that charge a fee are responsible for transferring the fees to the fee controller.*

## State Variables

### MAX\_IMPLEMENTATION\_FEE

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

### FeeControllerStorageLocation

```solidity
bytes32 private constant FeeControllerStorageLocation =
    0x9980cbcd1eea9936b8d3caaf89dd2ea96db52917f1123c39e72b02e9cb513100;
```

## Functions

### \_getFeeControllerStorage

```solidity
function _getFeeControllerStorage() internal pure returns (FeeControllerStorage storage $);
```

### constructor

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

### setImplementationFee

Sets the fee of the 'implementation' to 'newFee'. Only callable by the 'owner' of the MezzHub

```solidity
function setImplementationFee(address implementation, uint256 newFee) external virtual onlyHubOwner;
```

### collectFees

Transfers 'amount' of 'asset' to the owner of the Mezz Hub

```solidity
function collectFees(address asset, uint256 amount) external virtual onlyHubOwner;
```

### calculateFee

Returns the fee for 'amount' based on the 'asset' and 'implementation' Returns zero if 'asset' is not a denomination asset or the implementation does not have a fee

```solidity
function calculateFee(address asset, uint256 amount, address implementation) public view virtual returns (uint256);
```

### getFeeByImplementation

Returns the fee for 'implementation'. Returns zero if there is no fee

```solidity
function getFeeByImplementation(address implementation) public view returns (uint256);
```

### supportsInterface

*ERC165 support*

```solidity
function supportsInterface(bytes4 interfaceId)
    public
    view
    virtual
    override(ERC165Upgradeable, IERC165)
    returns (bool);
```

## Structs

### FeeControllerStorage

```solidity
struct FeeControllerStorage {
    mapping(address => uint256) _feeByImplementation;
}
```


# Events

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

**Author:** Daniel Yamagata & Naveen Ailawadi

A library for all events emitted throughout the Mezzanine protocol

## Events

### UpgradeProposed

```solidity
event UpgradeProposed(address newImplementation, uint256 pendingUpgradeSnapshot);
```

### UpgradeCanceled

```solidity
event UpgradeCanceled(address caller);
```

### OwnershipTransferCanceled

```solidity
event OwnershipTransferCanceled(address caller);
```

### ProtocolStateSet

```solidity
event ProtocolStateSet(DataTypes.ProtocolState state);
```

### ProtocolFrozen

```solidity
event ProtocolFrozen(address indexed freezer, uint256 freezeDuration, uint256 frozenSnapshot);
```

### ImplementationFrozenStateSet

```solidity
event ImplementationFrozenStateSet(address indexed implementation, bool frozen);
```

### DeploymentFrozenStateSet

```solidity
event DeploymentFrozenStateSet(address indexed freezer, address indexed deployment, bool frozen);
```

### DocumentRegistrySet

```solidity
event DocumentRegistrySet(address newDocumentRegistry);
```

### MezzDeployerSet

```solidity
event MezzDeployerSet(address newMezzDeployer);
```

### FeeControllerSet

```solidity
event FeeControllerSet(address newFeeController);
```

### DenominationAssetAddedToWhitelist

```solidity
event DenominationAssetAddedToWhitelist(address denominationAsset);
```

### DenominationAssetRemovedFromWhitelist

```solidity
event DenominationAssetRemovedFromWhitelist(address denominationAsset);
```

### DefenderAdded

```solidity
event DefenderAdded(address defender);
```

### DefenderRemoved

```solidity
event DefenderRemoved(address defender);
```

### MezzInstanceDeployed

```solidity
event MezzInstanceDeployed(
    address indexed creator,
    bytes32 indexed companyId,
    DataTypes.MezzInstance mezzInstance,
    address[] initialOwners,
    string name,
    string symbol
);
```

### GuardDeployed

```solidity
event GuardDeployed(
    address indexed creator, address indexed controlled, address indexed controller, bytes32 coreId, address newGuard
);
```

### DepartmentDeployed

```solidity
event DepartmentDeployed(address indexed creator, bytes32 coreId, address deployedDepartment);
```

### ModuleDeployed

```solidity
event ModuleDeployed(address indexed creator, bytes32 coreId, address deployedDepartment);
```

### AssetDeployed

```solidity
event AssetDeployed(address indexed creator, bytes32 coreId, address deployedAsset);
```

### GovernorDeployed

```solidity
event GovernorDeployed(address indexed creator, bytes32 coreId, address deployedGovernor);
```

### GuardSelectorDefaultAdded

```solidity
event GuardSelectorDefaultAdded(
    bytes32 indexed coreId, address indexed contractAddress, bytes4 indexed functionSelector
);
```

### GuardSelectorDefaultRemoved

```solidity
event GuardSelectorDefaultRemoved(
    bytes32 indexed coreId, address indexed contractAddress, bytes4 indexed functionSelector
);
```

### GuardContractDefaultAdded

```solidity
event GuardContractDefaultAdded(bytes32 indexed coreId, address indexed contractAddress);
```

### GuardContractDefaultRemoved

```solidity
event GuardContractDefaultRemoved(bytes32 indexed coreId, address indexed contractAddress);
```

### NewCoreVersionSet

```solidity
event NewCoreVersionSet(bytes32 indexed coreId, uint256 indexed version, address newImplementation);
```

### ContractUpgraded

```solidity
event ContractUpgraded(
    address indexed caller, bytes32 indexed coreId, uint256 indexed newVersion, address newImplementation
);
```

### CoreVersionDeleted

```solidity
event CoreVersionDeleted(bytes32 indexed coreId, uint256 indexed version, address implementation);
```

### CoreVersionReset

```solidity
event CoreVersionReset(bytes32 indexed coreId, uint256 indexed latestVersion, address priorImplementation);
```

### ContractResetToPatchedVersion

```solidity
event ContractResetToPatchedVersion(
    address indexed caller, bytes32 indexed coreId, uint256 indexed newVersion, address newImplementation
);
```

### DocumentAdded

```solidity
event DocumentAdded(
    address indexed documentOwner, uint256 indexed documentIndex, string indexed documentName, string documentUri
);
```

### DocumentUpdated

```solidity
event DocumentUpdated(
    address indexed documentOwner,
    uint256 indexed documentIndex,
    string indexed updatedDocumentName,
    string updatedDocumentUri,
    uint256 version
);
```

### ImplementationFeeSet

```solidity
event ImplementationFeeSet(address indexed implementationAddress, uint256 newFee);
```

### FeesCollected

```solidity
event FeesCollected(address indexed asset, address indexed hubOwner, uint256 collectionAmount);
```

### InvoiceSent

```solidity
event InvoiceSent(
    address indexed seller,
    address indexed billableParty,
    bytes32 indexed categoryId,
    bytes32 invoiceId,
    address denominationAsset,
    uint256 amount,
    uint256 dueDate,
    string description
);
```

### InvoicePaid

```solidity
event InvoicePaid(
    address indexed seller,
    address indexed billableParty,
    bytes32 indexed categoryId,
    bytes32 invoiceId,
    address payer,
    address denominationAsset,
    uint256 amountPaid,
    uint256 invoiceAmount
);
```

### InvoiceCanceled

```solidity
event InvoiceCanceled(
    address indexed seller,
    address indexed billableParty,
    bytes32 indexed categoryId,
    bytes32 invoiceId,
    address denominationAsset,
    uint256 amount,
    uint256 dueDate,
    uint256 documentIndex
);
```

### InvoiceDocumentUpdated

```solidity
event InvoiceDocumentUpdated(bytes32 indexed invoiceId, uint256 invoiceDocumentIndex, uint256 newDocumentVersion);
```

### AdminAdded

```solidity
event AdminAdded(address admin);
```

### AdminRemoved

```solidity
event AdminRemoved(address admin);
```

### ChildInserted

```solidity
event ChildInserted(address indexed child);
```

### ChildRemoved

```solidity
event ChildRemoved(address indexed child);
```

### AncestorAddedOwner

```solidity
event AncestorAddedOwner(address indexed ancestor, address indexed newOwner);
```

### AncestorRemovedOwner

```solidity
event AncestorRemovedOwner(address indexed ancestor, address indexed removedOwner);
```

### AncestorSwappedGuard

```solidity
event AncestorSwappedGuard(address indexed ancestor, bytes32 newGuardCoreId, address newGuard);
```

### AncestorChangedThreshold

```solidity
event AncestorChangedThreshold(address indexed ancestor, uint256 newThreshold);
```

### Spent

```solidity
event Spent(address indexed asset, uint256 amount, uint256 amountReceived);
```

### SharesIssued

```solidity
event SharesIssued(address indexed to, uint256 value);
```

### SharesAuthorized

```solidity
event SharesAuthorized(uint256 amount);
```

### SharesBurned

```solidity
event SharesBurned(address indexed from, uint256 amount);
```

### DelegateVotesChanged

```solidity
event DelegateVotesChanged(address indexed delegate, uint256 previousVotes, uint256 newVotes);
```

### AssetAddedToCapitalStack

```solidity
event AssetAddedToCapitalStack(address indexed asset, uint256 senioirtyLevelIndex, uint256 assetDocumentIndex);
```

### AssetRemovedFromCapitalStack

```solidity
event AssetRemovedFromCapitalStack(address indexed asset);
```

### ShareClassAdded

```solidity
event ShareClassAdded(address indexed shares);
```

### ShareClassRemoved

```solidity
event ShareClassRemoved(address indexed shares);
```

### GovernorChanged

```solidity
event GovernorChanged(bytes32 indexed governorCoreId, address newGovernor);
```

### PayrollSpent

```solidity
event PayrollSpent(address indexed asset, uint256 amount, uint256 amountPaid);
```

### ChildSpent

```solidity
event ChildSpent(address indexed asset, uint256 amount, uint256 fee);
```

### SharesVested

```solidity
event SharesVested(address indexed owner, address indexed shares, uint256 indexed tokenId, uint256 amountVested);
```

### SharesVestingCompleted

```solidity
event SharesVestingCompleted(
    address indexed owner, address indexed shares, uint256 indexed tokenId, uint256 totalAmountReleased
);
```

### SharesVestingCanceledAtTimepoint

```solidity
event SharesVestingCanceledAtTimepoint(
    address indexed owner,
    address indexed shares,
    uint256 indexed tokenId,
    address cancelor,
    uint256 amountCanceled,
    uint256 timepoint
);
```

### SharesVestingCanceled

```solidity
event SharesVestingCanceled(
    address indexed owner, address indexed shares, uint256 indexed tokenId, address cancelor, uint256 amountCanceled
);
```

### SharesVestingDurationExtended

```solidity
event SharesVestingDurationExtended(address indexed owner, uint256 indexed tokenId, uint256 durationExtension);
```

### SharesVestingAmountIncreased

```solidity
event SharesVestingAmountIncreased(
    address indexed owner, address indexed shares, uint256 indexed tokenId, address sender, uint256 equityExtension
);
```

### SharesReleased

```solidity
event SharesReleased(address indexed owner, address indexed shares, uint256 indexed tokenId, uint256 amountReleased);
```

### DelegateVotesChanged

```solidity
event DelegateVotesChanged(address indexed delegate, address shares, uint256 previousVotes, uint256 newVotes);
```

### SeniorityLevelAdded

```solidity
event SeniorityLevelAdded(
    uint256 indexed seniorityLevelIndex,
    uint8 indexed assetClass,
    uint256 previousSeniorityLevelIndex,
    uint256 nextSeniorityLevelIndex
);
```

### SeniorityLevelRemoved

```solidity
event SeniorityLevelRemoved(
    uint256 indexed seniorityLevelIndex,
    uint8 indexed assetClass,
    uint256 previousSeniorityLevelIndex,
    uint256 nextSeniorityLevelIndex
);
```

### AssetAdded

```solidity
event AssetAdded(uint256 indexed seniorityLevelIndex, address indexed asset, uint256 documentIndex);
```

### AssetRemoved

```solidity
event AssetRemoved(uint256 indexed seniorityLevelIndex, address indexed asset, uint256 documentIndex);
```

### AssetDocumentUpdated

```solidity
event AssetDocumentUpdated(address indexed asset, uint256 indexed documentIndex, uint256 newDocumentVersion);
```

### DelegateChanged

```solidity
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
```

### EmployeeHired

```solidity
event EmployeeHired(
    address indexed employee,
    uint256 indexed tokenId,
    address indexed hirer,
    uint256 startDate,
    uint256 annualCash,
    uint256 equityAmount,
    uint256 vestingDuration
);
```

### CashPaid

```solidity
event CashPaid(
    address indexed employee,
    uint256 indexed tokenId,
    address indexed recipient,
    address executor,
    address cashAsset,
    uint256 cashToTransfer,
    uint256 cashPaid,
    bytes32 encodedPaymentDetails
);
```

### EquityPaid

```solidity
event EquityPaid(
    address indexed employee,
    uint256 indexed tokenId,
    address indexed recipient,
    address executor,
    uint256 equityToTransfer,
    bytes32 encodedPaymentDetails
);
```

### EmployeeTerminated

```solidity
event EmployeeTerminated(address indexed employee, uint256 tokenId);
```

### UnpaidTimeOffIncreased

```solidity
event UnpaidTimeOffIncreased(address indexed employee, uint256 indexed tokenId, uint256 unpaidTimeOff);
```

### EmployeeResigned

```solidity
event EmployeeResigned(address indexed employee, uint256 tokenId, uint256 endDate);
```

### EmployeeRecipientChanged

```solidity
event EmployeeRecipientChanged(address indexed employee, uint256 indexed tokenId, address newRecipient);
```

### ActionProposed

```solidity
event ActionProposed(bytes32 indexed actionId, address indexed proposer);
```

### CashSalaryChangeProposed

```solidity
event CashSalaryChangeProposed(bytes32 indexed actionId, uint256 indexed tokenId, uint256 newCashSalary);
```

### CashPaymentProposed

```solidity
event CashPaymentProposed(
    bytes32 indexed actionId, uint256 indexed tokenId, uint256 cashPaymentAmount, bytes32 encodedPaymentDetails
);
```

### EquityPaymentProposed

```solidity
event EquityPaymentProposed(
    bytes32 indexed actionId, uint256 indexed tokenId, uint256 equityPaymentAmount, bytes32 encodedPaymentDetails
);
```

### EquityPaymentsExtensionProposed

```solidity
event EquityPaymentsExtensionProposed(
    bytes32 indexed actionId, uint256 indexed tokenId, uint256 equityExtension, uint256 durationExtension
);
```

### NewEquityPaymentsProposed

```solidity
event NewEquityPaymentsProposed(
    bytes32 indexed actionId,
    uint256 indexed tokenId,
    uint256 equityAmount,
    uint256 startDate,
    uint256 vestingDuration,
    uint256 vestingCliff,
    uint256 vestingInitialUnlock
);
```

### PendingActionCanceled

```solidity
event PendingActionCanceled(bytes32 indexed actionId, address indexed canceler);
```

### CashSalaryChanged

```solidity
event CashSalaryChanged(
    address indexed employee, uint256 indexed tokenId, bytes32 indexed actionId, uint256 newCashSalary
);
```

### ExtendedEquityPayments

```solidity
event ExtendedEquityPayments(
    address indexed employee,
    uint256 indexed tokenId,
    bytes32 indexed actionId,
    uint256 equityExtension,
    uint256 durationExtension
);
```

### NewEquityPaymentsSet

```solidity
event NewEquityPaymentsSet(
    address indexed employee,
    uint256 indexed tokenId,
    bytes32 indexed actionId,
    uint256 equityAmount,
    uint256 startDate,
    uint256 vestingDuration,
    uint256 vestingCliff,
    uint256 vestingInitialUnlock
);
```

### EmployeeDocumentUpdated

```solidity
event EmployeeDocumentUpdated(
    address indexed employee, uint256 indexed tokenId, uint256 documentIndex, uint256 newDocumentVersion
);
```

### VotingDelaySet

```solidity
event VotingDelaySet(uint256 newVotingDelay);
```

### VotingPeriodSet

```solidity
event VotingPeriodSet(uint256 newVotingPeriod);
```

### ProposalThresholdPercentageSet

```solidity
event ProposalThresholdPercentageSet(uint256 newProposalThresholdPercentage);
```

### QuorumPercentageSet

```solidity
event QuorumPercentageSet(uint256 newQuorumPercentage);
```

### ProposalCanceled

```solidity
event ProposalCanceled(uint256 proposalId, address canceler);
```

### ProposalExecuted

```solidity
event ProposalExecuted(uint256 proposalId, address executor);
```

### VoteCast

```solidity
event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);
```

### VoteCastWithParams

```solidity
event VoteCastWithParams(
    address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params
);
```

### Executed

```solidity
event Executed(
    address indexed target, bytes4 indexed functionSelector, address indexed executor, uint256 value, bytes data
);
```

### ProposalCreated

```solidity
event ProposalCreated(
    address indexed proposer,
    address indexed shareClass,
    uint256 proposalId,
    bytes4 action,
    uint256 voteStart,
    uint256 voteEnd,
    string description
);
```

### GovernorChangedTreasuryThreshold

```solidity
event GovernorChangedTreasuryThreshold(uint256 newTreasuryThreshold, uint256 oldThreshold);
```

### ShareClassBoardSeatsIncreased

```solidity
event ShareClassBoardSeatsIncreased(address indexed shareClass, uint256 newBoardSeats, uint256 increaseAmount);
```

### ShareClassBoardMemberAdded

```solidity
event ShareClassBoardMemberAdded(address indexed shareClass, address indexed boardMember);
```

### ShareClassBoardMemberRemoved

```solidity
event ShareClassBoardMemberRemoved(address indexed shareClass, address indexed boardMember);
```

### SelectorAddedToList

```solidity
event SelectorAddedToList(address indexed contractAddress, bytes4 indexed selector);
```

### SelectorRemovedFromList

```solidity
event SelectorRemovedFromList(address indexed contractAddress, bytes4 indexed selector);
```

### ContractAddedToList

```solidity
event ContractAddedToList(address indexed contractAddress);
```

### ContractRemovedFromList

```solidity
event ContractRemovedFromList(address indexed contractAddress);
```

### PricedRoundOpened

```solidity
event PricedRoundOpened(
    uint256 indexed newPricedRoundIndex,
    address pricedRoundAddress,
    uint256 totalSharesForRound,
    uint256 pricePerShare,
    uint256 targetRaise,
    uint256 minimumRaise
);
```

### InvestorAllocationSet

```solidity
event InvestorAllocationSet(address indexed investor, uint128 numberOfShares, int128 discountOrPremium);
```

### InvestorShareAllocationIncreased

```solidity
event InvestorShareAllocationIncreased(address indexed investor, uint128 amount, uint128 newShareAllocation);
```

### InvestorShareAllocationDecreased

```solidity
event InvestorShareAllocationDecreased(address indexed investor, uint128 amount, uint128 newShareAllocation);
```

### RoundOpened

```solidity
event RoundOpened(
    address owner,
    address treasury,
    address denominationAsset,
    address shares,
    uint128 minimumRaise,
    uint128 targetRaise
);
```

### MinimumRaiseIncreased

```solidity
event MinimumRaiseIncreased(uint128 minimumRaiseExtension, uint128 newMinimumRaise);
```

### RoundExtended

```solidity
event RoundExtended(
    uint128 targetRaiseExtension, uint128 totalSharesExtension, uint128 newTargetRaise, uint128 newTotalSharesForRound
);
```

### RoundCanceled

```solidity
event RoundCanceled(uint128 totalRaised, uint128 minimumRaise, uint128 targetRaise, uint128 totalSharesForRound);
```

### RoundClosed

```solidity
event RoundClosed(uint256 totalRaised, uint128 allottedShares);
```

### InvestedInRound

```solidity
event InvestedInRound(address indexed investor, uint128 investmentAmount, uint128 sharesOwed);
```

### InvestmentRevoked

```solidity
event InvestmentRevoked(address indexed investor, uint128 investmentAmount, uint128 sharesOwed);
```

### InvestmentRecouped

```solidity
event InvestmentRecouped(address indexed investor, uint128 investmentAmount, uint128 sharesOwed);
```

### SharesClaimed

```solidity
event SharesClaimed(address indexed investor, uint128 sharesClaimed, uint256 tokenTimelockTokenId);
```


# Errors

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

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

A library for all errors that can be thrown in the Mezzanine Protocol.  All errors in Mezzanine follow the following syntax:&#x20;

```solidity
error ContractNameErrorName(arg1, arg2, ...)
```

where *ContractName* is the name of the contract that the error originates, and *ErrorName* is the name of the error. The arguments are optional and are used to provide additional context to the error.&#x20;

{% hint style="info" %}
This part of the documentation is not meant to be read. It is meant to act as a resource for developers who may have a difficult time tracing errors when building on top of the Mezzanine protocol. The Ctrl-F command should be used to locate the error name or selector that is causing a reversion.
{% endhint %}

## Errors

### AlreadySet

The state variable to set is already set to the given value or part of a given set or mapping&#x20;

Selector: 0xa741a045

```solidity
error AlreadySet();
```

### NotSet

The state variable to remove is not set or is not part of a given set or mapping&#x20;

Selector: 0x441dfbd6

```solidity
error NotSet();
```

### SelfAddress

The provided address is the address of the contract&#x20;

Selector: 0x2007aa4c

```solidity
error SelfAddress();
```

### ZeroAddress

The passed-in address is the zero address, i.e. address(0)&#x20;

Selector: 0xd92e233d

```solidity
error ZeroAddress();
```

### ZeroAmount

The passed-in amount is zero&#x20;

Selector: 0x1f2a2005

```solidity
error ZeroAmount();
```

### NullCoreId

The passed-in core ID is the null, i.e. bytes32(0)&#x20;

Selector: 0x256d6403

```solidity
error NullCoreId();
```

### EmptyArray

The passed-in array is empty&#x20;

Selector: 0x521299a9

```solidity
error EmptyArray();
```

### InvalidSignature

An invalid signature was provided for 'account'&#x20;

Selector: 0xd855c4f4

```solidity
error InvalidSignature(address account);
```

### InputLengthMismatch

Multiple arrays are passed in but not of the same length&#x20;

Selector: 0xaaad13f7

```solidity
error InputLengthMismatch();
```

### CallerNotAuthorizedToPatch

The 'caller' is not authorized to patch via 'resetToPatchedLatestVersion()' in a contract that inherits from 'Patchable'&#x20;

Selector: 0x15d92cf7

```solidity
error CallerNotAuthorizedToPatch(address caller);
```

### TreasuryMismatch

The 'expectedTreasury' does not match the 'providedTreasury'. Thrown when inserting a department as a child and adding an asset into the capital stack&#x20;

Selector: 0x4c4808fc

```solidity
error TreasuryMismatch(address expectedTreasury, address providedTreasury);
```

### InvalidShares

The passed-in 'shares' to use for the token timelock, priced round, shareclass governor, etc. is not tracked by the treasury&#x20;

Selector: 0xc645bc49

```solidity
error InvalidShares(address shares);
```

### ProvidedTreasuryDoesNotSupportTreasuryInterface

The 'treasury' passed in during initialization does not support the treasury interface&#x20;

Selector: 0xd7cb9b7a

```solidity
error ProvidedTreasuryDoesNotSupportTreasuryInterface(address treasury);
```

### SafeModulesDisabled

Safe modules are disabled.  This error is thrown when:

1. A call is made to 'execTransactionFromModule()' of a Team, which inherits from Safe
2. A call is made to 'checkModuleTransaction()' in a Mezz Guard

Selector: 0x3965d7af

```solidity
error SafeModulesDisabled();
```

### InvalidDenominationAsset

The passed-in denomination asset is not whitelisted within the Mezz Hub&#x20;

Selector: 0x6b044bae

```solidity
error InvalidDenominationAsset(address denominationAsset);
```

### TransactionFailed

An arbitrary call to an address failed. Thrown when:

* A Safe, which Team inherits, calls 'checkAfterExecution()' during 'execTransaction()'
* The 'execTransaction()' during a Team's 'execMultipleTransactions()' failed&#x20;

Selector: 0xbf961a28

```solidity
error TransactionFailed();
```

### CannotReceiveNativeToken

The contract is unable to receive the blockchain's native token&#x20;

Selector: 0xa02752ed

```solidity
error CannotReceiveNativeToken();
```

### PrecisionLoss

Arithmetic produced a value of zero when it should have been greater than zero Precision loss in the protocol is almost always dependent on time-based calculations with extremely small values. Functions that cause this error are likely to function correctly once enough time has passed&#x20;

Selector: 0x63c8f3fb

```solidity
error PrecisionLoss();
```

## MaliciousUpgradeCalldata

The calldata used to call 'upgradeToAndCall()' is another call to 'upgradeToAndCall()', which is likely to be malicious

Selector: 0x03c16f1f

```solidity
error MaliciousUpgradeCalldata();
```

### HubOwnableCallerNotHubOwner

The 'caller' is not the 'owner' of the Mezz Hub&#x20;

Selector: 0x206e1fcc

```solidity
error HubOwnableCallerNotHubOwner(address caller);
```

### DelayedUUPSUpgradeableERC1967InvalidImplementation

The proposed upgrade has a code length of zero&#x20;

Selector: 0x4c719dc1

```solidity
error DelayedUUPSUpgradeableERC1967InvalidImplementation(address newImplementation);
```

### DelayedUUPSUpgradeableNewImplementationIsCurrentImplementation

The proposed upgrade is the same as the current implementation&#x20;

Selector: 0x972744aa

```solidity
error DelayedUUPSUpgradeableNewImplementationIsCurrentImplementation();
```

### DelayedUUPSUpgradeablePendingUpgradeInProgress

An upgrade was proposed. However, there is already an upgrade pending. The current pending upgrade must be canceled for a new upgrade to be proposed Selector:&#x20;

0xcee95171

```solidity
error DelayedUUPSUpgradeablePendingUpgradeInProgress(address pendingUpgrade);
```

### DelayedUUPSUpgradeableNoUpgradeProposed

'upgradeToAndCall()' was called. However, there is no pending upgrade&#x20;

Selector: 0x5ba5b862

```solidity
error DelayedUUPSUpgradeableNoUpgradeProposed();
```

### DelayedUUPSUpgradeableImplementationNotProposed

An attempt at an upgrade to 'newImplementation' was made. However, 'newImplementation' was not proposed&#x20;

Selector: 0xb3f596ce

```solidity
error DelayedUUPSUpgradeableImplementationNotProposed(address newImplementation);
```

### DelayedUUPSUpgradeableUpgradeNotReady

An attempt at an upgrade occurred. However, the 'pendingUpgradeSnapshot' has not passed yet&#x20;

Selector: 0x923c0d33

```solidity
error DelayedUUPSUpgradeableUpgradeNotReady(uint256 pendingUpgradeSnapshot);
```

### DelayedUUPSUpgradeableNoPendingUpgradeToCancel

An attempt to cancel the pending upgrade occurred. However, there is no upgrade pending&#x20;

Selector: 0x642d5ec5

```solidity
error DelayedUUPSUpgradeableNoPendingUpgradeToCancel();
```

### MezzHubCallerNotOwnerOrDefender

The caller attempted to call a function that is only callable by the 'owner' or a 'defender'&#x20;

Selector: 0xffa1c3e7

```solidity
error MezzHubCallerNotOwnerOrDefender(address caller);
```

### MezzHubOwnershipTransferAlreadyPending

An ownership transfer cannot be initiated because there is already an ownership transfer pending&#x20;

Selector: 0xf9cd2b72

```solidity
error MezzHubOwnershipTransferAlreadyPending();
```

### MezzHubOwnershipTransferNotReady

An attempt to accept an ownership transfer was made. However, the owner transfership is not ready&#x20;

Selector: 0x567b3c3d

```solidity
error MezzHubOwnershipTransferNotReady(uint256 transferSnapshot);
```

### MezzHubNoPendingOwnershipTransferToCancel

An attemp to cancel an ownership transfer that is non-existent&#x20;

Selector: 0x8b4f3e71

```solidity
error MezzHubNoPendingOwnershipTransferToCancel();
```

### MezzHubOwnershipRenouncementDisabled

Attempt to renounce ownership by the 'owner'. This is disabled to prevent griefing by a compromised 'owner'&#x20;

Selector: 0xecb099ff

```solidity
error MezzHubOwnershipRenouncementDisabled();
```

### MezzHubInvalidFreezeDuration

The passed in 'freezeDuration' is invalid, meaning it is either zero or greater than Constants.MAX\_FREEZE\_DURATION&#x20;

Selector: 0x5f7a0e96

```solidity
error MezzHubInvalidFreezeDuration(uint256 freezeDuration);
```

### MezzHubDocumentRegistryNotSet

Attempt to query the Document Registry when it has not been set&#x20;

Selector: 0xe110a858

```solidity
error MezzHubDocumentRegistryNotSet();
```

### MezzHubFeeControllerNotSet

Attempt to query the Fee Controller when it has not been set&#x20;

Selector: 0x495b7e87

```solidity
error MezzHubFeeControllerNotSet();
```

### MezzHubMezzDeployerNotSet

Attempt to query the Mezz Deployer when it has not been set&#x20;

Selector: 0x90e07ad0

```solidity
error MezzHubMezzDeployerNotSet();
```

### StateAwareProtocolStateFrozen

The protocol state is frozen in the Mezz Hub&#x20;

Selector: 0x893c4631

```solidity
error StateAwareProtocolStateFrozen();
```

### StateAwareProtocolStatePausedOrFrozen

The protocol state is paused or frozen in the Mezz Hub. The value of 'state' is reflected by the following enum:

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

Selector: 0x8619d7e0

```solidity
error StateAwareProtocolStatePausedOrFrozen(uint8 state);
```

### StateAwareImplementationFrozen

The 'implementation' is frozen in the Mezz Hub&#x20;

Selector: 0x9aa84a98

```solidity
error StateAwareImplementationFrozen(address implementation);
```

### StateAwareDeploymentFrozen

The 'deployment' is frozen in the Mezz Hub&#x20;

Selector: 0x4bfafc15

```solidity
error StateAwareDeploymentFrozen(address deployment);
```

### HubOwnableUUPSUpgradeableCallerNotAuthorizedToCancelUpgrade

The caller attempted to cancel an upgrade and is not the owner of the Mezz Hub nor a defender&#x20;

Selector: 0x16e79c7b

```solidity
error HubOwnableUUPSUpgradeableCallerNotAuthorizedToCancelUpgrade(address caller);
```

### MezzDeployerInvalidCompanyNameLength

The passed in company name has a length of zero or is greater than the max length&#x20;

Selector: 0x60a7a170

```solidity
error MezzDeployerInvalidCompanyNameLength(uint256 length);
```

### MezzDeployerInvalidCompanySymbolLength

The passed in company symbol has a length of zero or is greater than the max length&#x20;

Selector: 0x56ec764b

```solidity
error MezzDeployerInvalidCompanySymbolLength(uint256 length);
```

### MezzDeployerImplementationNotMezzGuard

The queried 'implementation' associated with 'coreId' does not support the mezz guard interface&#x20;

Selector: 0x0b46223a

```solidity
error MezzDeployerImplementationNotMezzGuard(bytes32 coreId, address implementation);
```

### MezzDeployerImplementationNotDepartment

The queried 'implementation' associated with 'coreId' does not support the department interface&#x20;

Selector: 0x6b02f768

```solidity
error MezzDeployerImplementationNotDepartment(bytes32 coreId, address implementation);
```

### MezzDeployerImplementationNotModule

The queried 'implementation' associated with 'coreId' does not support the module interface&#x20;

Selector: 0xb1a808c0

```solidity
error MezzDeployerImplementationNotModule(bytes32 coreId, address implementation);
```

### MezzDeployerImplementationNotAsset

The queried 'implementation' associated with 'coreId' does not support the asset interface&#x20;

Selector: 0xa93515ef

```solidity
error MezzDeployerImplementationNotAsset(bytes32 coreId, address implementation);
```

### MezzDeployerThresholdExceedsNumberOfOwners

The initial threshold to set is greater than the number of owners. 'owners' refer to a Safe's signers&#x20;

Selector: 0xa93515ef

```solidity
error MezzDeployerThresholdExceedsNumberOfOwners();
```

### MezzDeployerCompanyNameTaken

The company name is already taken&#x20;

Selector: 0x4a16a7b5

```solidity
error MezzDeployerCompanyNameTaken(string companyName);
```

### MezzDeployerCompanySymbolTaken

The company symbol is already taken&#x20;

Selector: 0x88adf994

```solidity
error MezzDeployerCompanySymbolTaken(string companySymbol);
```

### MezzDeployerInvalidGovernorCoreId

The provided 'coreId' for a governor is invalid&#x20;

Selector: 0x8e810482

```solidity
error MezzDeployerInvalidGovernorCoreId(bytes32 coreId);
```

### MezzDeployerInvalidCharacter

A company's name or symbol contains 'char', which is an invalid character&#x20;

Selector: 0xf8f3b4e6

```solidity
error MezzDeployerInvalidCharacter(bytes1 char);
```

### DocumentRegistryDocumentDoesNotExist

The document associated with 'documentIndex' for 'owner' does not exist&#x20;

Selector: 0xe1f5423e

```solidity
error DocumentRegistryDocumentDoesNotExist(address owner, uint256 documentIndex);
```

### FeeControllerNewImplementationFeeAboveMaxFee

The 'implementationFee' to set is above the maximum&#x20;

Selector: 0x689f650e

```solidity
error FeeControllerNewImplementationFeeAboveMaxFee(uint256 implementationFee);
```

### BillingRouterInvalidDueDate

The provided 'dueDate' is in the past&#x20;

Selector: 0xe5acd993

```solidity
error BillingRouterInvalidDueDate(uint256 dueDate);
```

### BillingRouterInvoiceAlreadyExists

The invoice already exists in the billing router&#x20;

Selector: 0xb2e02be8

```solidity
error BillingRouterInvoiceAlreadyExists(bytes32 invoiceId);
```

### BillingRouterCannotCancelPaidInvoice

The 'vendor' attempted to cancel an invoice that has already been paid&#x20;

Selector: 0x5fa6f33b

```solidity
error BillingRouterCannotCancelPaidInvoice(bytes32 invoiceId);
```

### BillingRouterCallerNotVendor

The 'caller' of the function is not the vendor&#x20;

Selector: 0x975582f5

```solidity
error BillingRouterCallerNotVendor(address caller);
```

### BillingRouterInvoiceDoesNotExist

There is no existing invoice associated with 'invoiceId'&#x20;

Selector: 0x588a04d6

```solidity
error BillingRouterInvoiceDoesNotExist(bytes32 invoiceId);
```

### MezzMigratorRedundantCoreIdProvidedDuringV1SetUp

A redundant 'coreId' was provided during the Mezz Migrator initialization&#x20;

Selector: 0xc975fc2a

```solidity
error MezzMigratorRedundantCoreIdProvidedDuringV1SetUp(bytes32 coreId);
```

### MezzMigratorImplementationDoesNotSupportCredentialedInterface

The 'implementation' does not support the 'ICredentialed' interface&#x20;

Selector: 0x7862e552

```solidity
error MezzMigratorImplementationDoesNotSupportCredentialedInterface(address implementation);
```

### MezzMigratorImplementationCoreIdMismatch

The 'implementationCoreId' does not match the passed-in 'coreId'. Thrown when setting a new core version, resetting the latest core version, or during the Mezz Migrator initialization&#x20;

Selector: 0x54144ed4

```solidity
error MezzMigratorImplementationCoreIdMismatch(bytes32 coreId, bytes32 implementationCoreId);
```

### MezzMigratorInvalidVersion

The provided 'version' is either zero or greater than the latest version&#x20;

Selector: 0xad0fc8ec

```solidity
error MezzMigratorInvalidVersion(uint256 version);
```

### MezzMigratorCallerAlreadyProposedVersion

The caller's version is greater than or equal to the new version that they are trying to upgrade to&#x20;

Selector: 0xa1eb9229

```solidity
error MezzMigratorCallerAlreadyProposedVersion();
```

### MezzMigratorVersionMismatch

The provided implementation's version is not equal to the passed in version&#x20;

Selector: 0x3160ebdc

```solidity
error MezzMigratorVersionMismatch(uint256 expectedVersion, uint256 implementationVersion);
```

### MezzMigratorCannotResetWhileImplementationActive

The caller cannot reset to the latest patched version while 'implementation' is active, meaning the protocol state is 'Active' and the implementation is not frozen&#x20;

Selector: 0x43ee0da5

```solidity
error MezzMigratorCannotResetWhileImplementationActive(address implementation);
```

### MezzMigratorLatestVersionZero

The latest version is zero when trying to patch a given implementation&#x20;

Selector: 0x87a8f6c6

```solidity
error MezzMigratorLatestVersionZero();
```

### MezzMigratorImplementationNotSet

The caller attempted to query an implementation or version for a 'coreId' whose implementation has not been set&#x20;

Selector: 0xfdf8145a

```solidity
error MezzMigratorImplementationNotSet(bytes32 coreId);
```

### VestingDurationZero

The passed-in vesting duration is zero&#x20;

Selector: 0x0dd7221d

```solidity
error VestingDurationZero();
```

### VestingInvalidInitialUnlockPercentage

The 'initialUnlockPercentage' is greater than Constants.PRECISION\_FACTOR, which represents 100%&#x20;

Selector: 0x3bf7bcf6

```solidity
error VestingInvalidInitialUnlockPercentage(uint256 initialUnlockPercentage);
```

### VestingCliffGreaterThanDuration

The passed-in vesting 'cliff' is greater than 'duration'&#x20;

Selector: 0x1c5412a1

```solidity
error VestingCliffGreaterThanDuration(uint256 duration, uint256 cliff);
```

### VestingInitialUnlockGreaterThanVestingAmount

The nominal 'initialUnlock' is greater than the 'vestingAmount'&#x20;

Selector: 0xeb373431

```solidity
error VestingInitialUnlockGreaterThanVestingAmount(uint256 vestingAmount, uint256 initialUnlock);
```

### VestingDifferenceBetweenAmountAndUnlockInsufficcient

The difference between the vesting amount and the initial unlock amount msut be greater than 1e10 to prevent potential reversion due to precision loss&#x20;

Selector: 0x4f08e754

```solidity
error VestingDifferenceBetweenAmountAndUnlockInsufficcient(uint256 vestingAmount, uint256 initialUnlock);
```

### VestingStartDateTooFarInFuture

The 'startDate' for the vesting is too far in the future as determined by Constants.MAX\_VESTING\_START\_DATE&#x20;

Selector: 0x03161d8a

```solidity
error VestingStartDateTooFarInFuture(uint256 startDate);
```

### VestingDurationIncreaseOverflow

The sum of the proposed 'durationExtension' and 'currentDuration' exceeds type(uint32).max

&#x20;Selector: 0x8d3d6a4c

```solidity
error VestingDurationIncreaseOverflow(uint256 currentDuration, uint256 durationExtension);
```

### MezzUUPSUpgradeableCallerUnauthorizedUpgrader

The 'caller' attempted to upgrade a proxy of a 'core' implementation to a new implementation. However, the 'caller' is not the Mezz Migrator&#x20;

Selector: 0x81607921

```solidity
error MezzUUPSUpgradeableCallerUnauthorizedUpgrader(address caller);
```

### TeamControlledTeamDoesNotSupportTeamInterface

The 'team' passed in during the team-controlled contract's initialization does not support the Team Interface&#x20;

Selector: 0x2d20894c

```solidity
error TeamControlledTeamDoesNotSupportTeamInterface(address team);
```

### TeamControlledCallerNotTeam

The caller is not the 'team', which acts as the admin of the contract&#x20;

Selector: 0x771ddc97

```solidity
error TeamControlledCallerNotTeam(address caller);
```

### BoardControlledCallerNotBoard

The 'caller' is not the Treasury, whose signers are the board of directors&#x20;

Selector: 0xc052d844

```solidity
error BoardControlledCallerNotBoard(address caller);
```

### BoardControlledCallerNotGovernance

The 'caller' is not the Treasury's governor&#x20;

Selector: 0xbfc0ce9d

```solidity
error BoardControlledCallerNotGovernance(address caller);
```

### AdminControlledCallerNotAdminOrBoard

The 'caller' is not an admin or the Treasury, whose signers are the board of directors&#x20;

Selector: 0xa1ac51e3

```solidity
error AdminControlledCallerNotAdminOrBoard(address caller);
```

### TeamChildToInsertParentMismatch

The parent of the 'childToInsert' does not match the address of the 'team' that it is being inserted into&#x20;

Selector: 0xe07ff662

```solidity
error TeamChildToInsertParentMismatch(address childToInsert, address parentOfChild);
```

### TeamChildToInsertDoesNotSupportDepartmentOrModuleInterface

The 'childToInsert' does not support the Department or Module interface. Checked via ERC165 supportsInterface()&#x20;

Selector: 0x0a0f12cf

```solidity
error TeamChildToInsertDoesNotSupportDepartmentOrModuleInterface(address childToInsert);
```

### TeamChildToInsertEquityFinancingModule

The child to insert is an Equity Financing Module. Checked by querying the 'coreId' of the child&#x20;

Selector: 0x9eed88ed

```solidity
error TeamChildToInsertEquityFinancingModule();
```

### TeamOwnerManagementInvalidSelector

```solidity
error TeamOwnerManagementInvalidSelector(bytes4 action);
```

### TeamInvalidExecTransactionInMultiCall

The 'functionSelector' provided in the multicall does not refert to execTransaction() but another function&#x20;

Selector: 0x3d8cb1c1

```solidity
error TeamInvalidExecTransactionInMultiCall(bytes4 functionSelector);
```

### TeamCallerNotChildOrThis

The caller is not a 'child' of the team or the team, itself&#x20;

Selector: 0xf04214db

```solidity
error TeamCallerNotChildOrThis(address caller);
```

### TeamCallerNotChild

The 'caller' is not a 'child' of the team&#x20;

Selector: 0x1644c4f0

```solidity
error TeamCallerNotChild(address caller);
```

### NotSolvent

The function within the team is only callable while solvent&#x20;

Selector: 0xe081c8f3

```solidity
error NotSolvent();
```

### NotLiquidating

The function within the team is only callable while liquidating&#x20;

Selector: 0xa97f9f86

```solidity
error NotLiquidating();
```

### MezzERC721CallerNotTokenOwner

The 'caller' is not the owner of 'tokenId'&#x20;

Selector: 0x81021dbf

```solidity
error MezzERC721CallerNotTokenOwner(uint256 tokenId, address caller);
```

### VotesDelegatorCallerNotDelegateRegistry

The 'caller' is not the delegate registry&#x20;

Selector: 0x48454317

```solidity
error VotesDelegatorCallerNotDelegateRegistry(address caller);
```

### AncestorLogicCallerNotAncestor

The 'caller' is not an ancestor of the 'team'

&#x20;Selector: 0x3fb3c6b8

```solidity
error AncestorLogicCallerNotAncestor(address caller, address team);
```

### AncestorLogicCallerNotAncestorOrAuthorized

The 'caller' is not the 'team', itself, or an ancestor of the 'team'&#x20;

Selector: 0x7ceae545

```solidity
error AncestorLogicCallerNotAncestorOrAuthorized(address caller, address team);
```

### SafeTxValdiationOwnerManagementDisabled

The following errors are thrown when a team attempts to modify its:

* Owners
* Threshold
* Guard
* Modules Changing these aspects of a team must follow strict logic set in the team, itself. This logic is bespoke and up to the implementation of the team to determine. A team attempted to add, remove, or swap one of its owners, i.e. signers. The 'selector' is the function selector which corresponds to adding, removing, or swapping an owner in a Safe&#x20;

Selector: 0x7d3024de

```solidity
error SafeTxValdiationOwnerManagementDisabled(bytes4 selector);
```

### SafeTxValdiationThresholdManagementDisabled

A team attempted to change is threshold&#x20;

Selector: 0xcdf5a018

```solidity
error SafeTxValdiationThresholdManagementDisabled();
```

### SafeTxValidationGuardManagementDisabled

A team attempted to change its guard&#x20;

Selector: 0xd099c4aa

```solidity
error SafeTxValidationGuardManagementDisabled();
```

### SafeTxValidationModuleManagementDisabled

A team attempted to enable a Safe module&#x20;

Selector: 0x7c52a6bc

```solidity
error SafeTxValidationModuleManagementDisabled();
```

### DepartmentChildToInsertIsAncestor

The 'childToInsert' is an ancestor of the department&#x20;

Selector: 0x7f6155bf

```solidity
error DepartmentChildToInsertIsAncestor(address childToInsert);
```

### GeneralDepartmentInvalidName

The provided department name is longer than 32 characters or null&#x20;

Selector: 0x19c72ab3

```solidity
error GeneralDepartmentInvalidName();
```

### MezzGuardCallerNotController

The 'caller' is not the controller of the Mezz Guard&#x20;

Selector: 0x31f36af0

```solidity
error MezzGuardCallerNotController(address caller);
```

### MezzGuardDelegateCallDisabled

Delegate calls are disabled for all teams&#x20;

Selector: 0x6021a295

```solidity
error MezzGuardDelegateCallDisabled();
```

### BlacklistGuardBlacklistedOperation

The team who uses the blacklist guard attempted to execute a blacklisted operation&#x20;

Selector: 0x737c920a

```solidity
error BlacklistGuardBlacklistedOperation(address to, bytes4 selector);
```

### WhitelistGuardNonWhitelistedOperation

The team who uses whitelist guard attempted to execute a non-whitelisted operation&#x20;

Selector: 0xc278988a

```solidity
error WhitelistGuardNonWhitelistedOperation(address to, bytes4 selector);
```

### TreasuryCallerNotGovernance

The caller is not the governor of the Treasury&#x20;

Selector: 0x016045e1

```solidity
error TreasuryCallerNotGovernance(address caller);
```

### TreasuryAddingAssetReentrancy

'addAssetToCapitalStack' was reentered&#x20;

Selector: 0xdcfc03c8

```solidity
error TreasuryAddingAssetReentrancy();
```

### TreasuryCannotAddCommonShares

An attempt was made to add Common Shares. However, a company can only have a single class of common shares&#x20;

Selector: 0xfe009a20

```solidity
error TreasuryCannotAddCommonShares();
```

### TreasuryMaxShareClassesReached

The addition of a new share class would exceed the maximum number of shares classes&#x20;

Selector: 0x9eae310b

```solidity
error TreasuryMaxShareClassesReached();
```

### TreasuryProposedGovernorChangeInvalid

The Treasury's current governor is the same type as the proposed change. If this attempt was done to upgrade to a new version, upgrades should be completed via the Mezz Migrator&#x20;

Selector: 0x83e563bb

```solidity
error TreasuryProposedGovernorChangeInvalid();
```

### TreasuryCallerNotPayrollManager

The caller is not the Payroll Manager&#x20;

Selector: 0x027fafad

```solidity
error TreasuryCallerNotPayrollManager(address caller);
```

### TreasuryCannotRemoveEquityFinancingModule

The Treasury is unable to remove the Equity Financing Module&#x20;

Selector: 0xe3ca07a5

```solidity
error TreasuryCannotRemoveEquityFinancingModule();
```

### TreasuryPayrollInvalidAsset

The payroll manager attempted to spend an asset that is not the common shares or the denomination asset&#x20;

Selector: 0x2b4ae809

```solidity
error TreasuryPayrollInvalidAsset(address asset);
```

### TreasuryCannotRemoveCommonShares

The board of directors is attempting to remove the common shares from the capital stack&#x20;

Selector: 0xe64cf198

```solidity
error TreasuryCannotRemoveCommonShares();
```

### TreasurySharesToRemoveNotRemovable

The 'removable()' of 'sharesToRemove' returned false, meaning the total supply is greater than zero&#x20;

Selector: 0xe64cf198

```solidity
error TreasurySharesToRemoveNotRemovable(address sharesToRemove);
```

### MezzSharesInsufficientAuthorizedSharesForIssuance

The 'sharesToIssue' exceeds the number of authorized shares&#x20;

Selector: 0xc3b42604

```solidity
error MezzSharesInsufficientAuthorizedSharesForIssuance(uint256 authorizedShares, uint256 sharesToIssue);
```

### MezzSharesInsufficientBalanceForBurn

The 'sharesToBurn' exceeds the 'callerBalance'&#x20;

Selector: 0x0cddc40a

```solidity
error MezzSharesInsufficientBalanceForBurn(uint256 callerBalance, uint256 sharesToBurn);
```

### MezzSharesNewAuthorizedSharesExceedsMaxSupply

The authorized shares exceeds \_maxSupply, which is overridden to return type(uint192).max

Selector: 0x69352a66

```solidity
error MezzSharesNewAuthorizedSharesExceedsMaxSupply();
```

### MezzSharesVotingWeightExceedsMax

The 'votingWeight' to initialize the shares exceds the max&#x20;

Selector: 0x97e67d47

```solidity
error MezzSharesVotingWeightExceedsMax(uint256 votingWeight);
```

### MezzSharesMisinputDuringIssuance

The duration is non-zero during the issuance of shares but at least one of the other arguments for vesting is non-null&#x20;

Selector: 0x12e5c2dd

```solidity
error MezzSharesMisinputDuringIssuance();
```

### MezzSharesDelegateDisabled

The caller attempted to delegate via the Mezz Shares rather than the delegate registry&#x20;

Selector: 0x61cb0201

```solidity
error MezzSharesDelegateDisabled();
```

### CommonSharesInvalidInitialAuthorizedShares

The initial authorized shares was below the minimum of 1e18 or above the maximum of 1\_000\_000\_000\_000e18&#x20;

Selector: 0xcc6ffc47

```solidity
error CommonSharesInvalidInitialAuthorizedShares(uint256 initialAuthorizedShares);
```

### PreferredSharesInvalidLiquidationPreference

The passed-in liquidation preference value to set during the Preferred Shares initialization exceeds the maximum

Selector: 0x97712678

```solidity
error PreferredSharesInvalidLiquidationPreference(uint256 liquidationPreference, uint256 maxLiquidationPreference);
```

### CapitalStackMaxSeniorityLevelsReached

The maximum number of seniority levels has been reached&#x20;

Selector: 0x42da71f8

```solidity
error CapitalStackMaxSeniorityLevelsReached();
```

### CapitalStackMaxAssetsForSeniorityLevelReached

The max number of assets for the seniority level with 'seniorityLevelIndex' has been reached&#x20;

Selector: 0xbb3513f6

```solidity
error CapitalStackMaxAssetsForSeniorityLevelReached(uint256 seniorityLevelIndex);
```

### CapitalStackProposedAssetClassIsInvalidForSeniorityLevelInsertion

The proposed 'assetClass' of the seniority level to insert is invalid&#x20;

Selector: 0x3851e38e

```solidity
error CapitalStackProposedAssetClassIsInvalidForSeniorityLevelInsertion(uint8 assetClass);
```

### CapitalStackInvalidPreviousSeniorityLevelIndexForInsertion

The 'previousSeniorityLevelIndex' has a null asset class and does not equal zero. This indicates that an an insertion was attempted to be made at a non-existent seniority level&#x20;

Selector: 0x9a9048a1

```solidity
error CapitalStackInvalidPreviousSeniorityLevelIndexForInsertion(uint256 previousSeniorityLevelIndex);
```

### CapitalStackPreviousAssetClassIsSeniorToProposedAssetClass

The 'previousSeniorityLevelAssetClass' is senior to the 'proposedAssetClass', violating the rules regarding the ordering of the capital stack&#x20;

Selector: 0xe9724aee

```solidity
error CapitalStackPreviousAssetClassIsSeniorToProposedAssetClass(
    uint8 previousSeniorityLevelAssetClass, uint8 proposedAssetClass
);
```

### CapitalStackNextAssetClassIsJuniorToProposedAssetClass

The 'previousNextSeniorityLevelAssetClass', which is the asset class of the next seniority level, is junior to the 'proposedAssetClass', violating the rules regarding the ordering of the capital stack&#x20;

Selector: 0x120f4a9e

```solidity
error CapitalStackNextAssetClassIsJuniorToProposedAssetClass(
    uint8 previousNextSeniorityLevelAssetClass, uint8 proposedAssetClass
);
```

### CapitalStackInvalidSeniorityLevel

The seniority level with 'seniorityLevelIndex' does not exist&#x20;

Selector: 0x20ae3881

```solidity
error CapitalStackInvalidSeniorityLevel(uint256 seniorityLevelIndex);
```

### CapitalStackCannotRemoveSeniorityLevelWithAssets

The seniority level with 'seniorityLevelIndexToRemove' still has assets in it, making it unremovable&#x20;

Selector: 0xc6e766ba

```solidity
error CapitalStackCannotRemoveSeniorityLevelWithAssets(uint256 seniorityLevelIndexToRemove);
```

### CapitalStackAssetToAddAlreadyInStack

The 'assetToAdd' is already in the capital stack

Selector: 0xe928901b

```solidity
error CapitalStackAssetToAddAlreadyInStack(address assetToAdd);
```

### CapitalStackAssetToInsertDoesNotSupportAssetInterface

The 'assetToAdd' does not support the IAsset interface&#x20;

Selector: 0xc8026364

```solidity
error CapitalStackAssetToInsertDoesNotSupportAssetInterface(address assetToAdd);
```

### CapitalStackAssetSeniorityLevelClassMismatch

The asset to add differs in its class from the asset class of the seniority level that it is trying to be inserted into&#x20;

Selector: 0x131227b0

```solidity
error CapitalStackAssetSeniorityLevelClassMismatch(uint8 assetClassOfAsset, uint8 assetClassOfSeniorityLevel);
```

### CapitalStackTreasuryAddingAssetHookFalse

The treasury is attempting to add an asset, but the Treasury's 'isAddingAsset' hook returned false&#x20;

Selector: 0x77cd8e11

```solidity
error CapitalStackTreasuryAddingAssetHookFalse();
```

### CapitalStackTreasuryRemovingAssetHookFalse

The treasury is attempting to remove an asset, but the Treasury's 'isRemovingAsset' hook returned false

Selector: 0xbf03703f

```solidity
error CapitalStackTreasuryRemovingAssetHookFalse();
```

### CapitalStackAssetNotInStack

'asset' is not in the capital stack. Thrown when attempting to remove an asset from the capital stack or updating an asset's document&#x20;

Selector: 0xcb83406f

```solidity
error CapitalStackAssetNotInStack(address asset);
```

### CapitalStackCannotRemoveCommonShares

The initial common shares of a company cannot be removed&#x20;

Selector: 0x0bea455e

```solidity
error CapitalStackCannotRemoveCommonShares();
```

### CapitalStackAssetNotRemovable

The 'removable()' condition built into 'asset' returned false, making it unremovable&#x20;

Selector: 0x6bdc2b25

```solidity
error CapitalStackAssetNotRemovable(address asset);
```

### TokenTimelockTokenIsObligatory

An admin or the board of directors attempted to cancel a vesting schedule that is obligatory&#x20;

Selector: 0xdd6f12e2

```solidity
error TokenTimelockTokenIsObligatory(uint256 tokenId);
```

### TokenTimelockNoReleaseableAmountForToken

An attempt was made to release an amount of vested tokens when there is no releasable amount&#x20;

Selector: 0x40e45f70

```solidity
error TokenTimelockNoReleaseableAmountForToken(uint256 tokenId);
```

### TokenTimelockCallerNotTokenOwnerOrAdmin

The caller is not the owner of the token nor an admin&#x20;

Selector: 0x805cccbf

```solidity
error TokenTimelockCallerNotTokenOwnerOrAdmin(address caller);
```

### TokenTimelockInvalidTimepointForCancel

A user tried to cancel vesting with an invalid 'timepoint'. 'timepoint' is after the vesting end date or in the past&#x20;

Selector: 0xc7fa0aae

```solidity
error TokenTimelockInvalidTimepointForCancel(uint256 timepoint);
```

### TokenTimelockVotesFutureLookup

The 'timepoint' when trying to query past votes is in the present or future&#x20;

Selector: 0xfba51db7

```solidity
error TokenTimelockVotesFutureLookup(uint256 timepoint, uint256 currentTimepoint);
```

### PayrollManagerStartDateInPastOrTooSoon

The 'startDate' when hiring an employee is in the past or too soon&#x20;

Selector: 0x68f559f6

```solidity
error PayrollManagerStartDateInPastOrTooSoon(uint256 startDate);
```

### PayrollManagerStartDateTooFarInFuture

The 'startDate' when hiring an employee is too far into the future&#x20;

Selector: 0x3391a3c8

```solidity
error PayrollManagerStartDateTooFarInFuture(uint256 startDate);
```

### PayrollManagerInvalidParamsLength

The 'paramsLength' is not equal to the expected length&#x20;

Selector: 0x3c1e54aa

```solidity
error PayrollManagerInvalidParamsLength(uint256 paramsLength, uint256 expectedLength);
```

### PayrollManagerNonExistentEquityPayments

'payrollTokenId' does not have a corresponding 'tokenTimelockTokenId' that exists This is either due to the completion of the previous equity vesting or a lack of a vesting schedule&#x20;

Selector: 0x58169333

```solidity
error PayrollManagerNonExistentEquityPayments(uint256 payrollTokenId, uint256 tokenTimelockTokenId);
```

### PayrollManagerInvalidResignationEndDate

The 'endDate' provided by the resigning employee is either in the past or too far in the future&#x20;

Selector: 0xe417ad1d

```solidity
error PayrollManagerInvalidResignationEndDate(uint256 endDate);
```

### PayrollManagerInvalidUnpaidTimeOff

The passed-in 'timeOff' to increase by is invalid. It is either zero or exceeds the maximum&#x20;

Selector: 0xded6374e

```solidity
error PayrollManagerInvalidUnpaidTimeOff(uint256 timeOff);
```

### PayrollManagerNoCollectibleCash

There is no collectible cash for 'tokenId'&#x20;

Selector: 0x00b9d8fa

```solidity
error PayrollManagerNoCollectibleCash(uint256 tokenId);
```

### PayrollManagerNoCollectableEquity

There is no collectible equity for 'tokenId'&#x20;

Selector: 0xba62285c

```solidity
error PayrollManagerNoCollectibleEquity(uint256 tokenId);
```

### PayrollManagerActionAlreadyPending

The proposed action with 'actionId' is already pending&#x20;

Selector: 0xf04013b8

```solidity
error PayrollManagerActionAlreadyPending(bytes32 actionId);
```

### PayrollManagerInvalidAction

The proposed 'action' does not correspond to a valid action. The 'action' is a function selector that does not match the ones that require an action to be proposed in the Payroll Manager&#x20;

Selector: 0x0f84a91a

```solidity
error PayrollManagerInvalidAction(bytes4 action);
```

### PayrollManagerActionNotPending

The pending action with 'actionId' to cancel was executed or does not exist&#x20;

Selector: 0xc0bbb966

```solidity
error PayrollManagerActionNotPending(bytes32 actionId);
```

### PayrollManagerCallerNotAuthorizedToCancel

The 'caller' is not authorized to cancel the pending action. The caller must be the board of directors, an admin, the 'owner' of the Mezz Hub, or a 'defender'

```solidity
error PayrollManagerCallerNotAuthorizedToCancel(address caller);
```

### PayrollManagerInvalidEquityExtension

The proposed equity extension has an equity and a duration extension of zero&#x20;

Selector: 0x3fce7621

```solidity
error PayrollManagerInvalidEquityExtension();
```

### PayrollManagerEquityPaymentsAlreadyExist

'tokenId' already has equity payments corresponding to the 'tokenTimelockTokenId'&#x20;

Selector: 0x5332635d

```solidity
error PayrollManagerEquityPaymentsAlreadyExist(uint256 tokenId, uint256 tokenTimelockTokenId);
```

### PayrollManagerActionNotReady

The pending action with 'actionId' is not ready to be executed&#x20;

Selector: 0xfca49f9b

```solidity
error PayrollManagerActionNotReady(bytes32 actionId, uint256 snapshot);
```

### PayrollManagerNotEmployee

The provided 'tokenId' does not correspond to an active employee&#x20;

Selector: 0x48a42e6b

```solidity
error PayrollManagerNotEmployee(uint256 tokenId);
```

### PayrollManagerCashSalaryAboveMaximum

The proposed 'cashSalary' is above the maximum&#x20;

Selector: 0xb4862033

```solidity
error PayrollManagerCashSalaryAboveMaximum(uint256 cashSalary);
```

### PayrollManagerNewCashSalarySameAsCurrent

The 'newCashSalary' is the same as the current cash salary&#x20;

Selector: 0x9924bb05

```solidity
error PayrollManagerNewCashSalarySameAsCurrent();
```

### PayrollManagerCashPaymentAboveMaximum

The 'cashPayment' is above the maximum&#x20;

Selector: 0x48033d83

```solidity
error PayrollManagerCashPaymentAboveMaximum(uint256 cashPayment);
```

### PayrollManagerInsufficientTreasurySharesBalance

The 'equityToTransfer' exceeds the treasury's balance of common shares. Thrown when hiring an employee, extending equity payments, setting new equity payments, or making a direct equity payment&#x20;

Selector: 0x50f401e2

```solidity
error PayrollManagerInsufficientTreasurySharesBalance(uint256 equityToTransfer, uint256 treasuryBalance);
```

### PayrollManagerInsufficientTreasuryCashBalance

The 'cashToTransfer' exceeds the treasury's balance of cash. Thrown only when paying a cash directly to an employee. If there is insufficcient cash during the collection of an employee's salary, their 'cashOwed' will be udpated such that they are able to redeem cash in the future&#x20;

Selector: 0xdd1f58be

```solidity
error PayrollManagerInsufficientTreasuryCashBalance(address cashAsset, uint256 cashToTransfer, uint256 treasuryBalance);
```

### PayrollManagerVestingEndDateGreaterThanEmployeeEndDate

The proposed new vesting schedule has an end date greater than the employee's end date&#x20;

Selector: 0x0b316f70

```solidity
error PayrollManagerVestingEndDateGreaterThanEmployeeEndDate(uint256 vestingEndDate, uint256 endDate);
```

### PayrollManagerInvalidEncodedDirectPaymentDetails

The direct payment details did not indicate that the payment was a 'Bonus' and/or a 'ContractorPayment'&#x20;

Selector: 0x11bd820a

```solidity
error PayrollManagerInvalidEncodedDirectPaymentDetails(bytes32 encodedPaymentDetails);
```

### PayrollManagerERC721BurnDisabled

Payroll Manager ERC721s cannot be burned&#x20;

Selector: 0x8ed8f671

```solidity
error PayrollManagerERC721BurnDisabled();
```

### PayrollManagerERC721Soulbound

Payroll Manager ERC721s are soulbound and cannot be transferred or approved for transfers&#x20;

Selector: 0x9a88eaad

```solidity
error PayrollManagerERC721Soulbound();
```

### PayrollManagerCannotReceiveERC721WhileNotTransacting

An account tried to 'safeTransfer' an ERC721 to the payroll manager while it was not transacting&#x20;

Selector: 0xa9398378

```solidity
error PayrollManagerCannotReceiveERC721WhileNotTransacting();
```

### MezzGovernorCallerNotGovernance

The 'caller' is not the governor contract, itself&#x20;

Selector: 0x05c401ea

```solidity
error MezzGovernorCallerNotGovernance(address caller);
```

### GovernorThresholdZero

The following errors are thrown both by the Share Class and Late Stage Governor and are not part of a a base class. Both governors throw the same errors to improve off-chain composability as well as to reduce redundancy The calculated proposal threshold is zero from precision loss or a total votes of zero&#x20;

Selector: 0x0b52725f

```solidity
error GovernorThresholdZero();
```

### GovernorQuorumZero

The calculated quorum is zero from precision loss or a total votes of zero&#x20;

Selector: 0x0c84d9ac

```solidity
error GovernorQuorumZero();
```

### GovernorSuperMajorityZero

The super majority is zero from precision loss or a total votes of zero&#x20;

Selector: 0x6066539f

```solidity
error GovernorSuperMajorityZero();
```

### GovernorCallerInvalidCanceler

The 'caller' is not the proposer or the 'owner' of the Mezz Hub&#x20;

Selector: 0xf50a2c1c

```solidity
error GovernorCallerInvalidCanceler(address caller);
```

### ProposalGovernorInvalidProposalThresholdPercentage

The 'newProposalThresholdPercentage' to set is greater than the max threshold percentage or less than the minimum threshold percentage&#x20;

Selector: 0xa6aaa345

```solidity
error ProposalGovernorInvalidProposalThresholdPercentage(uint256 newProposalThresholdPercentage);
```

### ProposalGovernorInvalidQuorumPercentage

The 'newQuorumPercentage' to set is greater than the max quorum percentage or less than the minimum quorum percentage&#x20;

Selector: 0x790521cb

```solidity
error ProposalGovernorInvalidQuorumPercentage(uint256 newQuorumPercentage);
```

### ProposalGovernorInvalidVotingDelay

The 'newVotingDelay' to set is greater than the max delay or less than the minimum delay&#x20;

Selector: 0x84378e36

```solidity
error ProposalGovernorInvalidVotingDelay(uint256 newVotingDelay);
```

### ProposalGovernorInvalidVotingPeriod

The 'newVotingPeriod' to set is greater than the max period or less than the minimum period&#x20;

Selector: 0x88bc198a

```solidity
error ProposalGovernorInvalidVotingPeriod(uint256 newVotingPeriod);
```

### ProposalGovernorInvalidVoteType

An invalid vote type was passed in&#x20;

Selector: 0x05703834

```solidity
error ProposalGovernorInvalidVoteType(uint8 support);
```

### ProposalGovernorAlreadyCastVote

The account has already voted on the proposal&#x20;

Selector: 0xc1e97f61

```solidity
error ProposalGovernorAlreadyCastVote(address account);
```

### StartupGovernorDeadlinePassed

The 'deadline' has passed for the proposed transaction&#x20;

Selector: 0xfab68f04

```solidity
error StartupGovernorDeadlinePassed(uint256 deadline);
```

### StartupGovernorInsufficcientBalance

The startup governor has the blockchain native currency balance of less than 'value' Selector: 0xe7df6f6b

```solidity
error StartupGovernorInsufficcientBalance(uint256 value);
```

### ShareClassGovernorBoardMemberAlreadySet

A proposal is attempting to add a board member that is already a board member&#x20;

Selector: 0x9612c52e

```solidity
error ShareClassGovernorBoardMemberAlreadySet(address ownerToAdd);
```

### ShareClassGovernorOwnerNotAddedByShareClass

A proposal for the a shareclass is attempting to remove a board member that was not added by the share class&#x20;

Selector: 0xb6693aa5

```solidity
error ShareClassGovernorOwnerNotAddedByShareClass(address ownerToRemove, address shareClass);
```

### ShareClassGovernorNoBoardSeatsAvailableForShareClass

There are no available board seats for the given share class&#x20;

Selector: 0x2d007190

```solidity
error ShareClassGovernorNoBoardSeatsAvailableForShareClass(address shareClass);
```

### ShareClassGovernorMaxPreferredBoardSeatsReached

The new allocated board seats from an increase is greater than the maximum for preferred shares&#x20;

Selector: 0x21af2cc0

```solidity
error ShareClassGovernorMaxPreferredBoardSeatsReached(uint256 newAllocatedBoardSeats);
```

### ShareClassGovernorInvalidAction

The provided action of a proposal does not correspond to managing owners in a treasury&#x20;

Selector: 0xf1133f15

```solidity
error ShareClassGovernorInvalidAction(bytes4 action);
```

### ShareClassGovernorInsufficcientProposerVotes

The proposer has less votes than the proposal threshold&#x20;

Selector: 0x00750c26

```solidity
error ShareClassGovernorInsufficcientProposerVotes(address proposer, uint256 proposerVotes, uint256 votesThreshold);
```

### ShareClassGovernorOwnerManagementDisabled

The board attempted to manage its signers via the Share Class Governor's executeTx()&#x20;

Selector: 0xa6c0564f

```solidity
error ShareClassGovernorOwnerManagementDisabled();
```

### ShareClassGovernorInvalidNewTreasuryThreshold

The 'newTreasuryThreshold' is greater than the number of signers or is zero&#x20;

Selector: 0x8788b74f

```solidity
error ShareClassGovernorInvalidNewTreasuryThreshold(uint256 newTreasuryThreshold);
```

### PricedRoundAllocationExceedsRemainingShares

The investor allocation to set or the increase to the investor allocation exceeds the 'remainingShares'&#x20;

Selector: 0x3ec91170

```solidity
error PricedRoundAllocationExceedsRemainingShares(uint256 remainingShares);
```

### PricedRoundDecreaseGreaterThanInvestorAllocation

The 'decreaseAmount' is larger than the 'sharesAllocation' of an investor&#x20;

Selector: 0x8e6d8f4e

```solidity
error PricedRoundDecreaseGreaterThanInvestorAllocation(uint256 decreaseAmount, uint256 sharesAllocation);
```

### PricedRoundNumberOfSharesMismatch

An investor's 'expectedNumberOfShares' does not equal their 'allocatedNumberOfShares' when investing in the round. Functions as frontrunning protection&#x20;

Selector: 0x15c069b1

```solidity
error PricedRoundNumberOfSharesMismatch(uint256 expectedNumberOfShares, uint256 allocatedNumberOfShares);
```

### PricedRoundDiscountOrPremiumMismatch

An investor's 'expectedDiscountOrPremium' does not equal their 'allocatedDiscountOrPremium' when investing in the round Functions as frontrunning protection&#x20;

Selector: 0xd3bfc752

```solidity
error PricedRoundDiscountOrPremiumMismatch(int256 expectedDiscountOrPremium, int256 allocatedDiscountOrPremium);
```

### PricedRoundInvestmentExceedsRemainingSharesForRound

The allotted shares following the investment would exceed the total shares for the round&#x20;

Selector: 0xcda9d7d9

```solidity
error PricedRoundInvestmentExceedsRemainingSharesForRound(uint256 allocationShares, uint256 remainingShares);
```

### PricedRoundInvestmentExceedsRemainingDenomAssetForRound

The 'investmentAmount' exceeds the 'remainingDenominationAsset' for the round&#x20;

Selector: 0x90f90b7a

```solidity
error PricedRoundInvestmentExceedsRemainingDenomAssetForRound(
    uint256 investmentAmount, uint256 remainingDenominationAsset
);
```

### PricedRoundUnexpectedRoundState

The round state is invalid for a given action&#x20;

Selector: 0x4ea2935c

```solidity
error PricedRoundUnexpectedRoundState(uint8 state);
```

### PricedRoundInvalidRaiseAmounts

The 'minimumRaise' is greater than the 'targetRaise'&#x20;

Selector: 0xef90e3cd

```solidity
error PricedRoundInvalidRaiseAmounts(uint256 minimumRaise, uint256 targetRaise);
```

### PricedRoundInvalidDiscount

The discount is larger than Constants.PRECISION\_FACTOR&#x20;

Selector: 0x07fffa63

```solidity
error PricedRoundInvalidDiscount(uint256 discount);
```

### PricedRoundInvalidPremium

The premium is larger than Constants.MAX\_PREMIUM

&#x20;Selector: 0xef9bd2a9

```solidity
error PricedRoundInvalidPremium(uint256 premium);
```

### PricedRoundCallerAllocationBelowMinimum

The 'caller' has an 'allocation' below the minimum, as defined by Constants.MIN\_INVESTOR\_ALLOCATION Thrown to prevent future precision loss&#x20;

Selector: 0xbdae0077

```solidity
error PricedRoundCallerAllocationBelowMinimum(address caller, uint256 allocation);
```

### PricedRoundInvestorNoInvestment

The 'investor' did not invest any tokens. Thrown when reversing an investment, whether that be recouping or revoking an investment&#x20;

Selector: 0xed42eb34

```solidity
error PricedRoundInvestorNoInvestment(address investor);
```

### PricedRoundInvestorNoShares

The 'investor' has no shares to claim

&#x20;Selector: 0xf0c98b72

```solidity
error PricedRoundInvestorNoShares(address investor);
```

### PricedRoundInsufficientRaise

'totalRaised' is not greater than the minimum raise&#x20;

Selector: 0x41efbf4a

```solidity
error PricedRoundInsufficientRaise();
```

### EquityFinancingModuleTeamNotDepartmentOrTreasury

The 'team' used for initialization does not support either the Treasury or Department interface&#x20;

Selector: 0x18cd71f6

```solidity
error EquityFinancingModuleTeamNotDepartmentOrTreasury(address team);
```

### EquityFinancingModuleCurrentPricedRoundUnexpectedState

An ancestor attempted to open a priced round, but the state of the current priced round is open or filled 'state' is defined by the DataTypes.RoundState enum:

* 0: Open
* 1: Closed
* 2: Filled
* 3: Cancelled&#x20;

Selector: 0x0c61feb2

```solidity
error EquityFinancingModuleCurrentPricedRoundUnexpectedState(uint8 state);
```


# Creating a Custom Module

Technical teams can easily create custom modules in Mezzanine to suit their needs (or as 3rd party software for other Mezzanine companies).  Mezzanine provides a base *Module* contract that can be inherited for hierarchical spending and access control. &#x20;

Below, we implement a custom module that exchanges a company's *common shares* for the company's *denomination asset* based on an exchange rate using Foundry.  This functionality is akin to share buybacks in traditional finance.  We will also be taking a 1%  fee, which will go to our wallet each time a share buyback is made. &#x20;

## Setup

Install Foundry via the following [tutorial](https://book.getfoundry.sh/getting-started/installation).

Run the following command to set up a new directory with *Foundry* set up:&#x20;

```bash
forge init custom_module_example
```

Go to the directory and install the OpenZeppelin contracts:

```bash
cd custom_module_example
forge install OpenZeppelin/openzeppelin-contracts
```

{% hint style="info" %}
The Mezzanine contracts are not public yet.  Therefore, they cannot yet be installed via Foundry.  They will be public soon.
{% endhint %}

Next, install the Mezzanine contracts:

```bash
forge install mezzanine-protocol/Mezzanine-Contracts
```

Change the *foundry.toml* file to look like the following:

```toml
[profile.default]
src = 'src'
out = 'out'
libs = ['lib']
remappings = ["@openzeppelin/=lib/openzeppelin-contracts/", "@mezzanine/=lib/Mezzanine-Contracts/src"]

# compiler version
solc-version = "0.8.20"

# See more config options https://github.com/foundry-rs/foundry/tree/master/config

```

## Modules Overview

A valid module must support the *IModule* interface:

```solidity
interface IModule is IERC165, IChild, ITeamControlled {
    /**
     * @notice Initializes the state of the module. This initialization is bespoke to each module
     * @param initTeam The team that controls the module
     * @param params The abi-encoded params to be decoded and passed to the module's initializer
     */
    function init(address initTeam, bytes memory params) external;
}
```

The initialization of a module is standardized.  All bespoke initialization arguments should be abi-encoded in the *params* argument.&#x20;

&#x20;*initTeam* should support the *Team* base contract, which both *departments* and *treasury* inherit.  This is unimportant for our purposes.  Just remember that *initTeam* should be a valid Mezzanine department or treasury.

*IModule* inherits from *IChild* and *ITeamControlled:*

```solidity
interface IChild {
    /**
     * @notice Returns the parent of 'this'. If 'this' is a department or module, returns the team that directly
     * controls 'this'. If 'this' is the Treasury, returns the sentinel parent, which is address(0x1)
     * @return The parent, which is either the treasury, a department, a module, or the sentinel parent
     */
    function getParent() external view returns (address);
}
```

```solidity
interface ITeamControlled {
    /**
     * @notice Returns the address of the team, which act similar to an 'owner' of the contract
     */
    function team() external view returns (address);
}
```

Both the *team* and *getParent* functions should return the same value for most modules.  However, this logic can be overridden if desired.&#x20;

We will be inheriting from Mezzanine's *Module* base contract, which provides an internal function to recursively spend funds from the organization's treasury given sufficient balances and approvals :&#x20;

```solidity
abstract contract Module is Initializable, ERC165Upgradeable, TeamControlled, IModule {
    constructor() {
        _disableInitializers();
    }

    /// @inheritdoc IModule
    function init(address initTeam, bytes memory params) external virtual;

    function __Module_init(address initTeam) internal virtual onlyInitializing {
        __TeamControlled_init(initTeam);
    }

    /**
     * @dev Recusrively spends 'amount' of 'asset' from the organization's treasury
     * @param asset The asset to spend
     * @param amount The amount to spend
     * @return The amount received
     */
    function _spend(address asset, uint256 amount) internal virtual returns (uint256) {
        uint256 moduleBeforeBalance = IERC20(asset).balanceOf(address(this));

        // Recursively spends from the organization's treasury
        ITeam(team()).spend(asset, amount);

        uint256 amountReceived = IERC20(asset).balanceOf(address(this)) - moduleBeforeBalance;

        emit Events.Spent(asset, amount, amountReceived);

        return amountReceived;
    }

    /// @inheritdoc IChild
    function getParent() public view virtual returns (address) {
        // The 'parent' of a module is the '_team' in TeamControlled
        return team();
    }

    /// @dev ERC165 support
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC165Upgradeable, IERC165)
        returns (bool)
    {
        return interfaceId == type(IModule).interfaceId || super.supportsInterface(interfaceId);
    }
}
```

Module inherits from *TeamControlled*, which is a base contract that provides modifiers for hierarchical and direct access control:&#x20;

```solidity
abstract contract TeamControlled is Initializable, ContextUpgradeable, ITeamControlled {
    /// @custom:storage-location erc7201:mezzanine.storage.TeamControlled.v1.0
    struct TeamControlledStorage {
        address _team;
    }

    // keccak256(abi.encode(uint256(keccak256("mezzanine.storage.TeamControlled.v1.0")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant TeamControlledStorageLocation =
        0xb816793abbf480753098fb767c6f1dcec3044cd562367c4739d88482505d6d00;

    function _getTeamControlledStorage() internal pure returns (TeamControlledStorage storage $) {
        assembly {
            $.slot := TeamControlledStorageLocation
        }
    }

    /// @dev Reverts if the caller is not the 'team'
    modifier onlyTeam() {
        _validateCallerIsTeam();
        _;
    }

    /// @dev Reverts if the caller is not the 'team' or its ancestor
    modifier onlyTeamOrAncestor() {
        _validateCallerIsTeamOrAncestor();
        _;
    }

    /// @dev Sets the '_team' variable and validate that it supports the ITeam interface
    function __TeamControlled_init(address initTeam) internal virtual onlyInitializing {
        if (!(ERC165Checker.supportsInterface(initTeam, type(ITeam).interfaceId))) {
            revert Errors.TeamControlledTeamDoesNotSupportTeamInterface(initTeam);
        }

        // Set 'team'
        TeamControlledStorage storage $ = _getTeamControlledStorage();
        $._team = initTeam;
    }

    /// @inheritdoc ITeamControlled
    function team() public view virtual returns (address) {
        TeamControlledStorage storage $ = _getTeamControlledStorage();
        return $._team;
    }

    function _isCallerTeam() internal view returns (bool) {
        return _msgSender() == team();
    }

    /// @dev Reverts if the caller is not the 'team'
    function _validateCallerIsTeam() internal view {
        if (!(_isCallerTeam())) revert Errors.TeamControlledCallerNotTeam(_msgSender());
    }

    /// @dev Reverts if the caller is not the 'team' or an ancestor of the 'team'
    function _validateCallerIsTeamOrAncestor() internal view {
        AncestorLogic.validateCallerIsTeamOrAncestor(team());
    }
}
```

## Writing the Custom Module

Our module should convert its company's common shares for the company's denomination asset based on an exchange rate.  This exchange rate should be set only by the module's ancestors.  This module should be deployed as a proxy.  We will be using EIP1167 minimal, non-upgradeable proxies.&#x20;

{% hint style="info" %}
The following code has not been audited and should not be deployed in production&#x20;
{% endhint %}

Here is the implementation of the *ShareBuybackModule*:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

import {ERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ITreasury} from "@mezzanine/core/treasury/ITreasury.sol";
import {Module} from "@mezzanine/core/modules/Module.sol";

/// @title Share Buyback Module
/// @dev ERC7201 storage slots are used to avoid storage collisions in the proxy contract
contract ShareBuybackModule is Module {
    using SafeCast for uint256;
    using SafeERC20 for IERC20;

    event ExchangeRateSet(address indexed setter, uint256 newExchangeRate);
    event SharesBoughtBack(address indexed seller, uint256 sharesSold, uint256 denominationAssetDistributed);
    event FeeDistributed(uint256 amount);

    address public immutable FEE_RECEIVER;

    // Percentages are represented as 100_000 = 100%
    uint256 public constant PRECISION_FACTOR = 100_000;
    uint256 public constant FEE_PERCENTAGE = 1_000; // 1_000/100_000 = 1%

    /// @custom:storage-location erc7201:mezzanine.storage.ShareBuybackModule.v1.0
    struct ShareBuybackModuleStorage {
        address _treasury;
        uint96 _exchangeRate;
    }

    // keccak256(abi.encode(uint256(keccak256("mezzanine.storage.ShareBuybackModule.v1.0")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant ShareBuybackModuleStorageLocation =
        0x3b8bfa8bd2e50cc6dc90186fa21102361a2dd4e0d242343ee79ef54ceffab400;

    function _getShareBuybackModuleStorage() internal pure returns (ShareBuybackModuleStorage storage $) {
        assembly {
            $.slot := ShareBuybackModuleStorageLocation
        }
    }

    constructor(address _feeReceiver) {
        _disableInitializers();

        require(_feeReceiver != address(0), "ShareBuybackModule: fee receiver cannot be the zero address");

        FEE_RECEIVER = _feeReceiver;
    }

    /**
     * @notice Initializes the ShareBuybackModule with the 'initTeam', which acts as an admin of the contract
     * @param initTeam The address of the team that will control the ShareBuybackModule
     * @param params The abi-encoded parameters used for initialization
     */
    function init(address initTeam, bytes memory params) external override initializer {
        __ShareBuybackModule_init(initTeam, params);
    }

    function __ShareBuybackModule_init(address initTeam, bytes memory params) internal onlyInitializing {
        (address __treasury, uint256 __exchangeRate) = abi.decode(params, (address, uint256));

        // Validate the decoded values
        require(__treasury != address(0), "ShareBuybackModule: treasury cannot be the zero address");
        require(__exchangeRate > 0, "ShareBuybackModule: exchange rate must be greater than zero");

        // Initialize state
        ShareBuybackModuleStorage storage $ = _getShareBuybackModuleStorage();
        $._treasury = __treasury;
        $._exchangeRate = __exchangeRate.toUint96();

        // Sets the 'team' and 'parent'
        __Module_init(initTeam);

        emit ExchangeRateSet(msg.sender, __exchangeRate);
    }

    /// @notice Returns the address of the 'treasury' contract as an ITreasury
    function treasury() public view returns (ITreasury) {
        ShareBuybackModuleStorage storage $ = _getShareBuybackModuleStorage();
        return ITreasury($._treasury);
    }

    /**
     * @notice Returns the exchange rate of shares to the denomination asset. For each share provided,
     * the caller will receive the 'exchangeRate' amount of the denomination asset
     * @dev The exchange rate should be set in the denomination asset's decimals
     */
    function exchangeRate() public view returns (uint256) {
        ShareBuybackModuleStorage storage $ = _getShareBuybackModuleStorage();
        return $._exchangeRate;
    }

    /// @notice Sets the exchange rate. Only callable by the 'team' or its ancestor
    function setExchangeRate(uint256 newExchangeRate) external onlyTeamOrAncestor {
        require(newExchangeRate > 0, "ShareBuybackModule: new exchange rate must be greater than zero");

        ShareBuybackModuleStorage storage $ = _getShareBuybackModuleStorage();
        $._exchangeRate = newExchangeRate.toUint96();

        emit ExchangeRateSet(msg.sender, newExchangeRate);
    }

    /**
     * @notice Allows the caller to sell 'sharesToBuy' amount of shares to the module in exchange for the denomination asset
     * @param amountToSell The amount of shares to sell
     * @param expectedExchangeRate The expected exchange rate
     */
    function sellShares(uint256 amountToSell, uint256 expectedExchangeRate) external {
        // Validate the exchange rate
        require(
            exchangeRate() >= expectedExchangeRate,
            "ShareBuybackModule: exchange rate lower than expected exchange rate"
        );

        ITreasury treasuryCache = treasury();

        // Get the 'denominationAsset' and 'commonShares' from the treasury
        address denominationAsset = treasuryCache.denominationAsset();
        address commonShares = treasuryCache.getCommonShares();

        uint256 denominationAssetOwed = calculateShareBuyback(amountToSell);
        uint256 fee = _calculateFee(denominationAssetOwed);

        // Transfer the 'commonShares' from the caller to the treasury
        IERC20(commonShares).safeTransferFrom(msg.sender, address(treasuryCache), amountToSell);

        // Spend's the denomination asset recursively from the organization's treasury. Defined in Module.sol
        _spend(denominationAsset, denominationAssetOwed + fee);

        // Transfer the 'denominationAsset' to the caller
        IERC20(denominationAsset).safeTransfer(msg.sender, denominationAssetOwed);

        _distributeFee(denominationAsset, fee);

        emit SharesBoughtBack(msg.sender, amountToSell, denominationAssetOwed);
    }

    /**
     * @notice Returns the amount of the denomination asset owed to the seller for the 'amountToSell' shares, uninclusive of fees
     * @param amountToSell The amount of shares to sell
     * @return The amount of the denomination asset owed to the seller in the units of the denomination asset
     */
    function calculateShareBuyback(uint256 amountToSell) public view returns (uint256) {
        address commonShares = treasury().getCommonShares();
        uint256 commonSharesUnits = 10 ** ERC20(commonShares).decimals();

        // The 'exchangeRate' is in the denomination asset's decimals.  The 'amountToSell' is in the common share's decimals.
        // Dividing the product of the 'amountToSell' and the 'exchangeRate' by the 'commonSharesUnits' will return the amount
        // of the denomination asset owed to the seller
        uint256 denominationAssetOwed = (amountToSell * exchangeRate()) / commonSharesUnits;

        if (denominationAssetOwed == 0 && amountToSell > 0) revert("ShareBuybackModule: precision loss");

        return denominationAssetOwed;
    }

    function _calculateFee(uint256 amount) internal pure returns (uint256) {
        return amount * FEE_PERCENTAGE / PRECISION_FACTOR;
    }

    function _distributeFee(address denominationAssetCache, uint256 fee) internal {
        IERC20(denominationAssetCache).safeTransfer(FEE_RECEIVER, fee);

        emit FeeDistributed(fee);
    }
}

```

Let's break it down. &#x20;

The *fee receiver* is set as an immutable variable in the constructor.  Since immutable variables are stored in [*runtime* rather than *storage*](https://medium.com/@ajaotosinserah/a-comprehensive-guide-to-implementing-constant-and-immutable-variables-in-solidity-4026ebadc6aa), the fee receiver will be the same across proxy deployments.

```solidity
    constructor(address _feeReceiver) {
        _disableInitializers();

        require(_feeReceiver != address(0), "ShareBuybackModule: fee receiver cannot be the zero address");

        FEE_RECEIVER = _feeReceiver;
    }
```

We use ERC7201 storage slots to prevent storage collisions in case an upgradeable proxy is used for the deployment:&#x20;

```solidity
    /// @custom:storage-location erc7201:mezzanine.storage.ShareBuybackModule.v1.0
    struct ShareBuybackModuleStorage {
        address _treasury;
        uint96 _exchangeRate;
    }

    // keccak256(abi.encode(uint256(keccak256("mezzanine.storage.ShareBuybackModule.v1.0")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant ShareBuybackModuleStorageLocation =
        0x3b8bfa8bd2e50cc6dc90186fa21102361a2dd4e0d242343ee79ef54ceffab400;

    function _getShareBuybackModuleStorage() internal pure returns (ShareBuybackModuleStorage storage $) {
        assembly {
            $.slot := ShareBuybackModuleStorageLocation
        }
    }
```

The initializer function decodes the initial exchange rate and the treasury's address from *params*.  Subsequently, it sets and validates the initial exchange rate and the treasury.  We make a call to the base contract Module's internal initializer function to set the *team*:

```solidity
    /**
     * @notice Initializes the ShareBuybackModule with the 'initTeam', which acts as an admin of the contract
     * @param initTeam The address of the team that will control the ShareBuybackModule
     * @param params The abi-encoded parameters used for initialization
     */
    function init(address initTeam, bytes memory params) external override initializer {
        __ShareBuybackModule_init(initTeam, params);
    }

    function __ShareBuybackModule_init(address initTeam, bytes memory params) internal onlyInitializing {
        (address __treasury, uint256 __exchangeRate) = abi.decode(params, (address, uint256));

        // Validate the decoded values
        require(__treasury != address(0), "ShareBuybackModule: treasury cannot be the zero address");
        require(__exchangeRate > 0, "ShareBuybackModule: exchange rate must be greater than zero");

        // Initialize state
        ShareBuybackModuleStorage storage $ = _getShareBuybackModuleStorage();
        $._treasury = __treasury;
        $._exchangeRate = __exchangeRate.toUint96();

        // Sets the 'team' and 'parent'
        __Module_init(initTeam);

        emit ExchangeRateSet(msg.sender, __exchangeRate);
    }
```

The exchange rate *must* be in the denomination asset's decimals.  We adjust for decimals when calculating the amount of denomination asset owed to a seller:

```solidity
    /**
     * @notice Returns the amount of the denomination asset owed to the seller for the 'amountToSell' shares, uninclusive of fees
     * @param amountToSell The amount of shares to sell
     * @return The amount of the denomination asset owed to the seller in the units of the denomination asset
     */
    function calculateShareBuyback(uint256 amountToSell) public view returns (uint256) {
        address commonShares = treasury().getCommonShares();
        uint256 commonSharesUnits = 10 ** ERC20(commonShares).decimals();

        // The 'exchangeRate' is in the denomination asset's decimals.  The 'amountToSell' is in the common share's decimals.
        // Dividing the product of the 'amountToSell' and the 'exchangeRate' by the 'commonSharesUnits' will return the amount
        // of the denomination asset owed to the seller
        uint256 denominationAssetOwed = (amountToSell * exchangeRate()) / commonSharesUnits;

        if (denominationAssetOwed == 0 && amountToSell > 0) revert("ShareBuybackModule: precision loss");

        return denominationAssetOwed;
    }
```

Finally, let's break down selling shares for a buyback.

First, we check for potential frontrunning. Since the exchange rate can be changed, a caller might call *sellShares* but be frontrun by the company.  The company can specifically frontrun the user such that the conversion rate is much lower than what user expected.  However, we validate this by requiring the exchange rate be *greater than or equal to* the user's expected rate.  If it is lower, the transaction will revert, protecting the user.

```solidity
        // Validate the exchange rate
        require(
            exchangeRate() >= expectedExchangeRate,
            "ShareBuybackModule: exchange rate lower than expected exchange rate"
        );
```

We next transfer the common shares from the user to the treasury.  A user should approve the share buyback module to spend their shares before attempting to sell their shares:&#x20;

```solidity
   // Transfer the 'commonShares' from the caller to the treasury
        IERC20(commonShares).safeTransferFrom(msg.sender, address(treasuryCache), amountToSell);
```

We finally *spend* the denomination asset from the organization's treasury.  We specifically spend the *denomination asset owed to the user* and *the fee* to send to the *fee receiver:*

```solidity
        // Spend's the denomination asset recursively from the organization's treasury
        _spend(denominationAsset, denominationAssetOwed + fee);

        // Transfer the 'denominationAsset' to the caller
        IERC20(denominationAsset).safeTransfer(msg.sender, denominationAssetOwed);

        _distributeFee(denominationAsset, fee);
```

Remember, the team that inserts this module must have approvals to spend the denomination asset from its parent, and its parent must have approvals to spend from its parent, etc.  A company should use ERC20 approvals as an upper limit for the number of shares to buybacks.  However, a more complex implementation may set this upper limit explicitly as a storage variable. &#x20;

## Deploying the Custom Module

Modules are assumed to be deployed as proxies via a *factory* or *deployer* contract.  The upgradeability logic of these proxies is up to the implementer.  We will deploy our custom module using non-upgradeable [EIP-1167](https://eips.ethereum.org/EIPS/eip-1167) minimal proxies via [OpenZeppelin's Clones library](https://docs.openzeppelin.com/contracts/4.x/api/proxy#minimal_clones) for simplicity.  The proxy *must be* initialized atomically upon its deployment. &#x20;

{% hint style="info" %}
To be upgradeable, the implementation should be changed to inherit [UUPSUpgradeable](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) and be deployed via[ ERC1967 Proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Proxy).  Access control regarding upgradeability must also be added to the implementation, itself.
{% endhint %}

Here is a simple factory contract for the module:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;

import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {ShareBuybackModule} from "./ShareBuybackModule.sol";

/// @title Share Buyback Module Factory
/// @notice Deploys and initializes ShareBuybackModule modules via EIP-1167 proxies
/// @dev Reference: https://eips.ethereum.org/EIPS/eip-1167
contract ShareBuybackModuleFactory {
    using Clones for address;

    event ShareBuybackModuleDeployed(address indexed creator, address indexed team, address module);

    address public immutable SHARE_BUYBACK_MODULE_IMPLEMENTATION;

    constructor(address _shareBuybackModuleImplementation) {
        SHARE_BUYBACK_MODULE_IMPLEMENTATION = _shareBuybackModuleImplementation;
    }

    /**
     * @notice Deploys and initializes a new ShareBuybackModule
     * @param team The address of the team that will control the ShareBuybackModule
     * @param params The abi-encoded parameters used for initialization
     * @return module The address of the newly deployed ShareBuybackModule
     */
    function deployShareBuybackModule(address team, bytes memory params) external returns (address) {
        address module = SHARE_BUYBACK_MODULE_IMPLEMENTATION.clone();
        ShareBuybackModule(module).init(team, params);

        emit ShareBuybackModuleDeployed(msg.sender, team, module);

        return module;
    }
}
```

{% hint style="info" %}
Deployment of the factory and the share buyback module can easily be completed via [Foundry's Solidity scripting](https://book.getfoundry.sh/tutorials/solidity-scripting)
{% endhint %}

{% hint style="info" %}
The testing of the module can easily be done via [Foundry's testing](https://book.getfoundry.sh/forge/tests).  Foundry's uses Solidity, itself, for its testing
{% endhint %}

## Security Considerations for Modules

All modules should be properly audited before being used by an organization. Teams should set their ERC20 approvals for a module to zero or remove the module from their organization if a route for exploitation is discovered. The upgradeability and security mechanisms for the module are up to the implementer. &#x20;

## Optimizations for the Share Buyback Module Contract

The above implementation of the Share Buyback Module is a very simple contract.  Here are some potential optimizations that can be made:

* The use of custom error reverts rather than strings&#x20;
* Buybacks of different share classes
* Buybacks using different denomination assets
* SLOAD optimizations
* ERC165 support


