CapitalStack
Last updated
Last updated
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
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
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 |
---|---|---|
Seniority levels are represented by a circular, doubly linked list. Their indexes are not assumed to be sequential
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
Parameters
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
Parameters
Returns
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
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
Case (B): An insertion at the front of the list
Case (C): An insertion at the back of the list
Cases (A) and (D): An insertion in an empty list or in the middle of the list, respectively
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.
Parameters
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
Parameters
Returns
Adds an asset to the seniority level at 'seniorityLevelIndex' and creates a document for the asset
Returns
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
Parameters
Updates an asset's document in the document registry
Returns
Returns information regarding a seniority level as a 'DataTypes.SeniorityLevelInfo' struct
Returns an empty struct if the seniority level does not exist
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
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
Returns zero if the asset is not in the stack. Otherwise, returns the seniority level index for 'asset'
Returns the number of assets in the seniority level with 'seniorityLevelIndex'
Will also returns zero if the seniority level does not exist
Returns true if 'asset' is in the capital stack, false otherwise
Returns the total number of seniority levels
Returns the document index for 'asset'
Reverts if 'asset' is not in the stack
Reverts if 'asset' has not been added to the capital stack
Creates a new document in the document registry, sets the '_documentIndexByAsset' mapping, and returns the document index
This function is kept as virtual in case overflow protection is desired in the future
This function is kept as virtual in case overflow protection is desired in the future
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"))
Returns the version of the implementation as a uint256
ERC165 support
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'
Parameters
Access control for 'resetToPatchedLatestVersion()'
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
Name | Type | Description |
---|---|---|
2
Debt
D, E, F, G
3
Preferred Equity
B, C
1
Common Equity
A
initTreasury
address
The treasury to be used by the capital stack
commonShares
address
The address of the common shares
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
<none>
uint256
The index of the newly inserted seniority level
seniorityLevelIndexToRemove
uint256
The index of the seniority level to remove
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
<none>
uint256
The document index for the asset
<none>
uint256
The document index for the asset
assetToRemove
address
The address of the asset to remove
<none>
uint256
The new version of the document, which is originally indexed at zero
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