# 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;
}
```


---

# 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/source-code/core/pricedround.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.
