# 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="/files/zyBjZv9NyE3CVWWuYfY9" 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="/files/zB0YkkEQ7r2Iwpw28R4Z" 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="/files/wqlHyZXgvhyhdnJa93VR" 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="/files/79TYA3YkhzRcIVGPe4wJ" 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="/files/KSVzbHCRck4ZQtoAkGkS" 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="/files/RMejAPlaEP44tmBHo9X5" 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="/files/fT4V8ix8v2qXeXlZg6x8" alt=""><figcaption><p>Blacklist Guard's <em>checkTransaction function</em></p></figcaption></figure>

<figure><img src="/files/mk6f67kjGCP6oQhhQhFj" 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mezzanine.xyz/smart-contracts/mezz-guards.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
