# MezoAllocator

## IMezoPortal

*Interface for the Mezo's Portal contract connected to dispatcher.*

### DepositInfo

DepositInfo keeps track of the deposit balance and unlock time. Each deposit is tracked separately and associated with a specific token. Some tokens can be deposited but can not be locked - in that case the unlockAt is the block timestamp of when the deposit was created. The same is true for tokens that can be locked but the depositor decided not to lock them. Some deposits can mint a receipt tokens against them: receiptMinted is the amount of receipt tokens minted against a deposit, while feeOwed is the fee owed by the deposit to Portal, and the lastFeeIntegral is the last updated value of the fee integral.

```solidity
struct DepositInfo {
  uint96 balance;
  uint32 unlockAt;
  uint96 receiptMinted;
  uint96 feeOwed;
  uint88 lastFeeIntegral;
}
```

### deposit

```solidity
function deposit(address token, uint96 amount, uint32 lockPeriod) external
```

Deposit and optionally lock tokens for the given period.

*Lock period will be normalized to weeks. If non-zero, it must not be shorter than the minimum lock period and must not be longer than the maximum lock period.*

#### Parameters

| Name       | Type    | Description                                       |
| ---------- | ------- | ------------------------------------------------- |
| token      | address | token address to deposit                          |
| amount     | uint96  | amount of tokens to deposit                       |
| lockPeriod | uint32  | lock period in seconds, 0 to not lock the deposit |

### withdraw

```solidity
function withdraw(address token, uint256 depositId) external
```

Withdraws all deposited tokens.

```
    Deposited lockable tokens can be withdrawn at any time if
    there is no lock set on the deposit or the lock period has passed.
    There is no way to withdraw locked deposit. Tokens that are not
    lockable can be withdrawn at any time.

    Deposits for which receipt tokens were minted and not fully
    repaid can not be withdrawn even if the lock expired. Repaying
    all receipt tokens is a must to withdraw the deposit. Upon
    withdrawing a deposit for which the receipt tokens were minted,
    the fee is collected based on the annual fee and the amount
    of minted receipt tokens.

    This function withdraws all deposited tokens. For partial
    withdrawals, use `withdrawPartially`.
```

#### Parameters

| Name      | Type    | Description             |
| --------- | ------- | ----------------------- |
| token     | address | deposited token address |
| depositId | uint256 | id of the deposit       |

### withdrawPartially

```solidity
function withdrawPartially(address token, uint256 depositId, uint96 amount) external
```

Withdraws part of the deposited tokens.

```
    Deposited lockable tokens can be withdrawn at any time if
    there is no lock set on the deposit or the lock period has passed.
    There is no way to withdraw locked deposit. Tokens that are not
    lockable can be withdrawn at any time.

    Deposits for which receipt tokens were minted and fully repaid
    can not be partially withdrawn even if the lock expired.
    Repaying all receipt tokens is a must to partially withdraw the
    deposit. If the fee for receipt tokens minted is non-zero, the
    deposit can not be partially withdrawn and only a full
    withdrawal is possible.

    This function allows only for partial withdrawals. For full
    withdrawals, use `withdraw`.
```

#### Parameters

| Name      | Type    | Description                |
| --------- | ------- | -------------------------- |
| token     | address | deposited token address    |
| depositId | uint256 | id of the deposit          |
| amount    | uint96  | the amount to be withdrawn |

### depositCount

```solidity
function depositCount() external view returns (uint256)
```

The number of deposits created. Includes the deposits that were fully withdrawn. This is also the identifier of the most recently created deposit.

### getDeposit

```solidity
function getDeposit(address depositor, address token, uint256 depositId) external view returns (struct IMezoPortal.DepositInfo)
```

Get the balance and unlock time of a given deposit.

#### Parameters

| Name      | Type    | Description                      |
| --------- | ------- | -------------------------------- |
| depositor | address | depositor address                |
| token     | address | token address to get the balance |
| depositId | uint256 | id of the deposit                |

## MezoAllocator

MezoAllocator routes tBTC to/from MezoPortal.

### mezoPortal

```solidity
contract IMezoPortal mezoPortal
```

Address of the MezoPortal contract.

### tbtc

```solidity
contract IERC20 tbtc
```

tBTC token contract.

### stbtc

```solidity
contract stBTC stbtc
```

stBTC token vault contract.

### isMaintainer

```solidity
mapping(address => bool) isMaintainer
```

Keeps track of the addresses that are allowed to trigger deposit allocations.

### maintainers

```solidity
address[] maintainers
```

List of maintainers.

### depositId

```solidity
uint256 depositId
```

keeps track of the latest deposit ID assigned in Mezo Portal.

### depositBalance

```solidity
uint96 depositBalance
```

Keeps track of the total amount of tBTC allocated to MezoPortal.

### DepositAllocated

```solidity
event DepositAllocated(uint256 oldDepositId, uint256 newDepositId, uint256 addedAmount, uint256 newDepositAmount)
```

Emitted when tBTC is deposited to MezoPortal.

### DepositWithdrawn

```solidity
event DepositWithdrawn(uint256 depositId, uint256 amount)
```

Emitted when tBTC is withdrawn from MezoPortal.

### MaintainerAdded

```solidity
event MaintainerAdded(address maintainer)
```

Emitted when the maintainer address is updated.

### MaintainerRemoved

```solidity
event MaintainerRemoved(address maintainer)
```

Emitted when the maintainer address is updated.

### DepositReleased

```solidity
event DepositReleased(uint256 depositId, uint256 amount)
```

Emitted when tBTC is released from MezoPortal.

### CallerNotMaintainer

```solidity
error CallerNotMaintainer()
```

Reverts if the caller is not a maintainer.

### CallerNotStbtc

```solidity
error CallerNotStbtc()
```

Reverts if the caller is not the stBTC contract.

### MaintainerNotRegistered

```solidity
error MaintainerNotRegistered()
```

Reverts if the maintainer is not registered.

### MaintainerAlreadyRegistered

```solidity
error MaintainerAlreadyRegistered()
```

Reverts if the maintainer has been already registered.

### onlyMaintainer

```solidity
modifier onlyMaintainer()
```

### constructor

```solidity
constructor() public
```

### initialize

```solidity
function initialize(address _mezoPortal, address _tbtc, address _stbtc) public
```

Initializes the MezoAllocator contract.

#### Parameters

| Name         | Type    | Description                         |
| ------------ | ------- | ----------------------------------- |
| \_mezoPortal | address | Address of the MezoPortal contract. |
| \_tbtc       | address | Address of the tBTC token contract. |
| \_stbtc      | address |                                     |

### allocate

```solidity
function allocate() external
```

Allocate tBTC to MezoPortal. Each allocation creates a new "rolling" deposit meaning that the previous Acre's deposit is fully withdrawn before a new deposit with added amount is created. This mimics a "top up" functionality with the difference that a new deposit id is created and the previous deposit id is no longer in use.

*This function can be invoked periodically by a maintainer.*

### withdraw

```solidity
function withdraw(uint256 amount) external
```

Withdraws tBTC from MezoPortal and transfers it to stBTC. This function can withdraw partial or a full amount of tBTC from MezoPortal for a given deposit id.

#### Parameters

| Name   | Type    | Description                 |
| ------ | ------- | --------------------------- |
| amount | uint256 | Amount of tBTC to withdraw. |

### releaseDeposit

```solidity
function releaseDeposit() external
```

Releases deposit in full from MezoPortal.

*This is a special function that can be used to migrate funds during allocator upgrade or in case of emergencies.*

### addMaintainer

```solidity
function addMaintainer(address maintainerToAdd) external
```

Adds a new maintainer address.

#### Parameters

| Name            | Type    | Description                    |
| --------------- | ------- | ------------------------------ |
| maintainerToAdd | address | Address of the new maintainer. |

### removeMaintainer

```solidity
function removeMaintainer(address maintainerToRemove) external
```

Removes the maintainer address.

#### Parameters

| Name               | Type    | Description                          |
| ------------------ | ------- | ------------------------------------ |
| maintainerToRemove | address | Address of the maintainer to remove. |

### totalAssets

```solidity
function totalAssets() external view returns (uint256)
```

Returns the total amount of tBTC allocated to MezoPortal including the amount that is currently hold by this contract.

### getMaintainers

```solidity
function getMaintainers() external view returns (address[])
```

Returns the list of maintainers.
