# Contracts API

## ContractRegistry

*Inherits from* [*Multicall*](#multicall)*,* [*ContractMeta*](#contractmeta)

⛽ 1.82M

### Functions

#### constructor

```solidity
  function constructor(address _governance) public
```

#### addresses

```solidity
  function addresses() external returns (address[])
```

Addresses of the registered contracts

#### names

```solidity
  function names() external returns (string[] result)
```

Names of the registered contracts

#### versions

```solidity
  function versions(string name_) external returns (string[] result)
```

All versions of the contract

**Parameters:**

| Name   | Type   | Description          |
| ------ | ------ | -------------------- |
| `name` | string | Name of the contract |

#### versionAddress

```solidity
  function versionAddress(string name_, string version) external returns (address)
```

Address of the contract at a given version

**Parameters:**

| Name      | Type   | Description             |
| --------- | ------ | ----------------------- |
| `name`    | string | Name of the contract    |
| `version` | string | Version of the contract |

#### latestVersion

```solidity
  function latestVersion(string name_) external returns (string, address)
```

Latest version of the contract

**Parameters:**

| Name   | Type   | Description          |
| ------ | ------ | -------------------- |
| `name` | string | Name of the contract |

#### registerContract

⛽ 256K (254K - 259K)

```solidity
  function registerContract(address target) external
```

Register a new contract

**Parameters:**

| Name     | Type    | Description                              |
| -------- | ------- | ---------------------------------------- |
| `target` | address | Address of the contract to be registered |

**Specs**

* ✅ registers IContractMeta compatible contract and updates respective view methods - #addresses - #versions - #names - #latestVersion - #versionAddress

*Access control*

* ✅ allowed: operator (deployer)
* ✅ denied with FRB: random address
* ✅ allowed: protocol admin

*Edge cases*

* ✅ when new contract major version differs more, than on one reverts with INVA
* ✅ when new contract version lower or equal existing one reverts with INVA
* ✅ when contract has invalid version reverts with INVA
* ✅ when contract name is not alphanumeric reverts with INV
* ✅ when address is already registered reverts with DUP

### Events

#### ContractRegistered

```solidity
  event ContractRegistered(address origin, address sender, bytes32 name, bytes32 version, address target)
```

## ProtocolGovernance

*Inherits from* [*Multicall*](#multicall)*,* [*UnitPricesGovernance*](#unitpricesgovernance)*,* [*DefaultAccessControl*](#defaultaccesscontrol)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*ContractMeta*](#contractmeta)

⛽ 4.68M

Governance that manages all params common for Mellow Permissionless Vaults protocol.

### Functions

#### constructor

```solidity
  function constructor(address admin) public
```

Creates a new contract

**Parameters:**

| Name    | Type    | Description                   |
| ------- | ------- | ----------------------------- |
| `admin` | address | Initial admin of the contract |

**Specs**

* ✅ deploys a new contract

#### stagedParams

```solidity
  function stagedParams() public returns (struct IProtocolGovernance.Params)
```

Staged pending protocol parameters.

**Specs**

* ✅ imestamp timestamp equals #stageParams's block.timestamp + governanceDelay
* ✅ imestamp clears by #commitParams
* ✅ imestamp edge cases when nothing is set returns zero
* ✅ imestamp access control allowed: any address

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ updates by #stageParams
* ✅ clears by #commitParams

#### params

```solidity
  function params() public returns (struct IProtocolGovernance.Params)
```

Current protocol parameters.

#### stagedValidatorsAddresses

```solidity
  function stagedValidatorsAddresses() external returns (address[])
```

#### validatorsAddresses

```solidity
  function validatorsAddresses() external returns (address[])
```

Addresses that has validators.

#### validatorsAddress

```solidity
  function validatorsAddress(uint256 i) external returns (address)
```

Address that has validators.

**Parameters:**

| Name | Type    | Description           |
| ---- | ------- | --------------------- |
| `i`  | uint256 | The number of address |

**Return Values:**

| Name        | Type    | Description |
| ----------- | ------- | ----------- |
| `Validator` | address | address     |

**Specs**

* ✅ returns correct value
* ✅ s properties @property: updates when committed validator grant for a new address
* ✅ s properties @property: doesn't update when committed validator grant for an existing address
* ✅ s access control allowed: any address

#### permissionAddresses

```solidity
  function permissionAddresses() external returns (address[])
```

Addresses for which non-zero permissions are set.

#### stagedPermissionGrantsAddresses

```solidity
  function stagedPermissionGrantsAddresses() external returns (address[])
```

Permission addresses staged for commit.

#### addressesByPermission

```solidity
  function addressesByPermission(uint8 permissionId) external returns (address[] addresses)
```

Return all addresses where rawPermissionMask bit for permissionId is set to 1.

**Parameters:**

| Name           | Type  | Description                    |
| -------------- | ----- | ------------------------------ |
| `permissionId` | uint8 | Id of the permission to check. |

**Return Values:**

| Name | Type       | Description              |
| ---- | ---------- | ------------------------ |
| `A`  | address\[] | list of dirty addresses. |

**Specs**

* ✅ returns addresses that has the given permission set to true

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ updates by #stagePermissionGrants + #commitPermissionGrants or #revokePermissions
* ✅ is not affected by forceAllowMask
* ✅ returns empty array on unknown permissionId

#### hasPermission

```solidity
  function hasPermission(address target, uint8 permissionId) external returns (bool)
```

Checks if address has permission or given permission is force allowed for any address.

**Parameters:**

| Name           | Type    | Description         |
| -------------- | ------- | ------------------- |
| `addr`         | address | Address to check    |
| `permissionId` | uint8   | Permission to check |

#### hasAllPermissions

```solidity
  function hasAllPermissions(address target, uint8[] permissionIds) external returns (bool)
```

Checks if address has all permissions.

**Parameters:**

| Name            | Type     | Description                    |
| --------------- | -------- | ------------------------------ |
| `target`        | address  | Address to check               |
| `permissionIds` | uint8\[] | A list of permissions to check |

**Specs**

* ✅ checks if an address has all permissions set to true

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ returns false on random address
* ✅ is not affected by staged permissions
* ✅ is affected by committed permissions
* ✅ returns true for any address when forceAllowMask is set to true

*Edge cases*

* ✅ on unknown permission id returns false

#### maxTokensPerVault

```solidity
  function maxTokensPerVault() external returns (uint256)
```

Max different ERC20 token addresses that could be managed by the protocol.

**Specs**

* ✅ returns correct value

#### governanceDelay

```solidity
  function governanceDelay() external returns (uint256)
```

The delay for committing any governance params.

**Specs**

* ✅ returns correct value

#### protocolTreasury

```solidity
  function protocolTreasury() external returns (address)
```

The address of the protocol treasury.

**Specs**

* ✅ returns correct value

#### forceAllowMask

```solidity
  function forceAllowMask() external returns (uint256)
```

Permissions mask which defines if ordinary permission should be reverted. This bitmask is xored with ordinary mask.

**Specs**

* ✅ returns correct value

#### withdrawLimit

```solidity
  function withdrawLimit(address token) external returns (uint256)
```

Withdraw limit per token per block.

**Parameters:**

| Name    | Type    | Description          |
| ------- | ------- | -------------------- |
| `token` | address | Address of the token |

**Return Values:**

| Name       | Type    | Description               |
| ---------- | ------- | ------------------------- |
| `Withdraw` | uint256 | limit per token per block |

**Specs**

* ✅ returns correct value

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

**Specs**

* ✅ returns true for IProtocolGovernance interface (0xca11fe03)
* ✅ access control: allowed: any address
* ✅ edge cases: when contract does not support the given interface returns false

#### stageValidator

⛽ 129K (43K - 142K)

```solidity
  function stageValidator(address target, address validator) external
```

Stages a new validator for the given address

**Parameters:**

| Name        | Type    | Description                         |
| ----------- | ------- | ----------------------------------- |
| `target`    | address | The given address                   |
| `validator` | address | The validator for the given address |

**Specs**

* ✅ emits ValidatorStaged event

*Access control*

* ✅ allowed: admin
* ✅ denied: deployer
* ✅ denied: random address

*Edge cases*

* ✅ when attempting to stage grant to zero address reverts with AZ when target has zero address
* ✅ when attempting to stage grant to zero address reverts with AZ when validator has zero address

#### rollbackStagedValidators

⛽ 39K (28K - 42K)

```solidity
  function rollbackStagedValidators() external
```

Rollback all staged validators.

**Specs**

* ✅ rolls back all staged validators
* ✅ emits AllStagedValidatorsRolledBack event

*Access control*

* ✅ allowed: admin
* ✅ denied: deployer
* ✅ denied: random address

#### commitValidator

⛽ 86K (47K - 117K)

```solidity
  function commitValidator(address stagedAddress) external
```

Commits validator for the given address.

📕 Reverts if governance delay has not passed yet.

**Parameters:**

| Name     | Type    | Description        |
| -------- | ------- | ------------------ |
| `target` | address | The given address. |

**Specs**

* ✅ commits staged validators
* ✅ emits ValidatorCommitted event

*Access control*

* ✅ allowed: admin
* ✅ denied: deployer
* ✅ denied: random address

*Edge cases*

* ✅ when attempting to commit validator for zero address reverts with NULL
* ✅ when nothing is staged for the given address reverts with NULL
* ✅ when attempting to commit validator too early reverts with TS

#### commitAllValidatorsSurpassedDelay

⛽ 132K (27K - 463K)

```solidity
  function commitAllValidatorsSurpassedDelay() external returns (address[] addressesCommitted)
```

Commites all staged validators for which governance delay passed

**Return Values:**

| Name        | Type       | Description                         |
| ----------- | ---------- | ----------------------------------- |
| `Addresses` | address\[] | for which validators were committed |

**Specs**

* ✅ emits ValidatorCommitted event

*Access control*

* ✅ allowed: admin
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ commits all staged validators
* ✅ commits all staged validators after delay

*Edge cases*

* ✅ when attempting to commit a single validator too early does not commit validator
* ✅ when attempting to commit multiple validators too early does not commit these validators

#### revokeValidator

⛽ 38K

```solidity
  function revokeValidator(address target) external
```

Revoke validator instantly from the given address.

**Parameters:**

| Name     | Type    | Description       |
| -------- | ------- | ----------------- |
| `target` | address | The given address |

**Specs**

* ✅ emits ValidatorRevoked event

*Edge cases*

* ✅ when attempting to revoke from zero address reverts with NULL

#### rollbackStagedPermissionGrants

⛽ 37K (28K - 42K)

```solidity
  function rollbackStagedPermissionGrants() external
```

Rollback all staged granted permission grant.

**Specs**

* ✅ rolls back all staged permission grants
* ✅ emits AllStagedPermissionGrantsRolledBack event

*Access control*

* ✅ allowed: admin
* ✅ denied: deployer
* ✅ denied: random address

#### commitPermissionGrants

⛽ 71K (46K - 117K)

```solidity
  function commitPermissionGrants(address stagedAddress) external
```

Commits permission grants for the given address.

📕 Reverts if governance delay has not passed yet.

**Parameters:**

| Name     | Type    | Description        |
| -------- | ------- | ------------------ |
| `target` | address | The given address. |

**Specs**

* ✅ commits staged permission grants
* ✅ emits PermissionGrantsCommitted event

*Access control*

* ✅ allowed: admin
* ✅ denied: deployer
* ✅ denied: random address

*Edge cases*

* ✅ when attempting to commit permissions for zero address reverts with NULL
* ✅ when nothing is staged for the given address reverts with NULL
* ✅ when attempting to commit permissions too early reverts with TS

#### commitAllPermissionGrantsSurpassedDelay

⛽ 145K (27K - 248K)

```solidity
  function commitAllPermissionGrantsSurpassedDelay() external returns (address[] addresses)
```

Commites all staged permission grants for which governance delay passed.

**Return Values:**

| Name | Type       | Description                                                    |
| ---- | ---------- | -------------------------------------------------------------- |
| `An` | address\[] | array of addresses for which permission grants were committed. |

**Specs**

* ✅ emits PermissionGrantsCommitted event

*Access control*

* ✅ allowed: admin
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ commits all staged permission grants
* ✅ commits all staged permission grants after delay

*Edge cases*

* ✅ when attempting to commit a single permission too early does not commit permission
* ✅ when attempting to commit multiple permissions too early does not commit these permissions

#### revokePermissions

⛽ 62K (32K - 275K)

```solidity
  function revokePermissions(address target, uint8[] permissionIds) external
```

Revoke permission instantly from the given address.

**Parameters:**

| Name            | Type     | Description                         |
| --------------- | -------- | ----------------------------------- |
| `target`        | address  | The given address.                  |
| `permissionIds` | uint8\[] | A list of permission ids to revoke. |

**Specs**

* ✅ emits PermissionRevoked event

*Edge cases*

* ✅ when attempting to revoke from zero address reverts with NULL

#### commitParams

⛽ 66K (54K - 81K)

```solidity
  function commitParams() external
```

Commits staged protocol params. Reverts if governance delay has not passed yet.

**Specs**

* ✅ emits ParamsCommitted event

*Access control*

* ✅ allowed: protocol admin
* ✅ denied: deployer
* ✅ denied: random address

*Edge cases*

* ✅ when attempting to commit params too early reverts with TS
* ✅ when attempting to commit params without setting pending params reverts with NULL

#### stagePermissionGrants

⛽ 166K (44K - 383K)

```solidity
  function stagePermissionGrants(address target, uint8[] permissionIds) external
```

Stage granted permissions that could have been committed after governance delay expires. Resets commit delay and permissions if there are already staged permissions for this address.

**Parameters:**

| Name            | Type     | Description                       |
| --------------- | -------- | --------------------------------- |
| `target`        | address  | Target address                    |
| `permissionIds` | uint8\[] | A list of permission ids to grant |

**Specs**

* ✅ emits PermissionGrantsStaged event

*Access control*

* ✅ allowed: admin
* ✅ denied: deployer
* ✅ denied: random address

*Edge cases*

* ✅ when attempting to stage grant to zero address reverts with NULL

#### stageParams

⛽ 140K (62K - 165K)

```solidity
  function stageParams(struct IProtocolGovernance.Params newParams) external
```

Sets new pending params that could have been committed after governance delay expires.

**Parameters:**

| Name        | Type                              | Description                     |
| ----------- | --------------------------------- | ------------------------------- |
| `newParams` | struct IProtocolGovernance.Params | New protocol parameters to set. |

**Specs**

* ✅ emits ParamsStaged event

*Access control*

* ✅ allowed: admin
* ✅ denied: random address

*Edge cases*

* ✅ when given invalid params when maxTokensPerVault is zero reverts with NULL
* ✅ when given invalid params when governanceDelay is zero reverts with NULL
* ✅ when given invalid params when governanceDelay exceeds MAX\_GOVERNANCE\_DELAY reverts with LIMO
* ✅ when given invalid params when withdrawLimit less than MIN\_WITHDRAW\_LIMIT reverts with LIMO

### Structs

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

```solidity
struct Params {
    uint256 maxTokensPerVault;
    uint256 governanceDelay;
    address protocolTreasury;
    uint256 forceAllowMask;
    uint256 withdrawLimit;
}
```

### Events

#### ValidatorStaged

```solidity
  event ValidatorStaged(address origin, address sender, address target, address validator, uint256 at)
```

Emitted when validators are staged to be granted for specific address.

**Parameters:**

| Name        | Type    | Description                                              |
| ----------- | ------- | -------------------------------------------------------- |
| `origin`    | address | Origin of the transaction (tx.origin)                    |
| `sender`    | address | Sender of the call (msg.sender)                          |
| `target`    | address | Target address                                           |
| `validator` | address | Staged validator                                         |
| `at`        | uint256 | Timestamp when the staged permissions could be committed |

#### ValidatorRevoked

```solidity
  event ValidatorRevoked(address origin, address sender, address target)
```

Validator revoked

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |
| `target` | address | Target address                        |

#### AllStagedValidatorsRolledBack

```solidity
  event AllStagedValidatorsRolledBack(address origin, address sender)
```

Emitted when staged validators are rolled back

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |

#### ValidatorCommitted

```solidity
  event ValidatorCommitted(address origin, address sender, address target)
```

Emitted when staged validators are comitted for specific address

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |
| `target` | address | Target address                        |

#### PermissionGrantsStaged

```solidity
  event PermissionGrantsStaged(address origin, address sender, address target, uint8[] permissionIds, uint256 at)
```

Emitted when new permissions are staged to be granted for specific address.

**Parameters:**

| Name            | Type     | Description                                              |
| --------------- | -------- | -------------------------------------------------------- |
| `origin`        | address  | Origin of the transaction (tx.origin)                    |
| `sender`        | address  | Sender of the call (msg.sender)                          |
| `target`        | address  | Target address                                           |
| `permissionIds` | uint8\[] | Permission IDs to be granted                             |
| `at`            | uint256  | Timestamp when the staged permissions could be committed |

#### PermissionsRevoked

```solidity
  event PermissionsRevoked(address origin, address sender, address target, uint8[] permissionIds)
```

Emitted when permissions are revoked

**Parameters:**

| Name            | Type     | Description                           |
| --------------- | -------- | ------------------------------------- |
| `origin`        | address  | Origin of the transaction (tx.origin) |
| `sender`        | address  | Sender of the call (msg.sender)       |
| `target`        | address  | Target address                        |
| `permissionIds` | uint8\[] | Permission IDs to be revoked          |

#### AllStagedPermissionGrantsRolledBack

```solidity
  event AllStagedPermissionGrantsRolledBack(address origin, address sender)
```

Emitted when staged permissions are rolled back

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |

#### PermissionGrantsCommitted

```solidity
  event PermissionGrantsCommitted(address origin, address sender, address target)
```

Emitted when staged permissions are comitted for specific address

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |
| `target` | address | Target address                        |

#### ParamsStaged

```solidity
  event ParamsStaged(address origin, address sender, uint256 at, struct IProtocolGovernance.Params params)
```

Emitted when pending parameters are set

**Parameters:**

| Name     | Type                              | Description                                              |
| -------- | --------------------------------- | -------------------------------------------------------- |
| `origin` | address                           | Origin of the transaction (tx.origin)                    |
| `sender` | address                           | Sender of the call (msg.sender)                          |
| `at`     | uint256                           | Timestamp when the pending parameters could be committed |
| `params` | struct IProtocolGovernance.Params | Pending parameters                                       |

#### ParamsCommitted

```solidity
  event ParamsCommitted(address origin, address sender, struct IProtocolGovernance.Params params)
```

Emitted when pending parameters are committed

**Parameters:**

| Name     | Type                              | Description                           |
| -------- | --------------------------------- | ------------------------------------- |
| `origin` | address                           | Origin of the transaction (tx.origin) |
| `sender` | address                           | Sender of the call (msg.sender)       |
| `params` | struct IProtocolGovernance.Params | Committed parameters                  |

## UnitPricesGovernance

*Inherits from* [*DefaultAccessControl*](#defaultaccesscontrol)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)

⛽ 1.82M

### Functions

#### constructor

```solidity
  function constructor(address admin) public
```

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

#### stageUnitPrice

⛽ 72K (54K - 74K)

```solidity
  function stageUnitPrice(address token, uint256 value) external
```

Stage estimated amount of token worth 1 USD staged for commit.

**Parameters:**

| Name    | Type    | Description          |
| ------- | ------- | -------------------- |
| `token` | address | Address of the token |
| `value` | uint256 | The amount of token  |

#### rollbackUnitPrice

⛽ 31K (30K - 31K)

```solidity
  function rollbackUnitPrice(address token) external
```

Reset staged value

**Parameters:**

| Name    | Type    | Description          |
| ------- | ------- | -------------------- |
| `token` | address | Address of the token |

#### commitUnitPrice

⛽ 50K

```solidity
  function commitUnitPrice(address token) external
```

Commit staged unit price

**Parameters:**

| Name    | Type    | Description          |
| ------- | ------- | -------------------- |
| `token` | address | Address of the token |

### Structs

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### UnitPriceStaged

```solidity
  event UnitPriceStaged(address origin, address sender, address token, uint256 unitPrice)
```

UnitPrice staged for commit

**Parameters:**

| Name        | Type    | Description                           |
| ----------- | ------- | ------------------------------------- |
| `origin`    | address | Origin of the transaction (tx.origin) |
| `sender`    | address | Sender of the call (msg.sender)       |
| `token`     | address | Token address                         |
| `unitPrice` | uint256 | Unit price                            |

#### UnitPriceRolledBack

```solidity
  event UnitPriceRolledBack(address origin, address sender, address token)
```

UnitPrice rolled back

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |
| `token`  | address | Token address                         |

#### UnitPriceCommitted

```solidity
  event UnitPriceCommitted(address origin, address sender, address token, uint256 unitPrice)
```

UnitPrice committed

**Parameters:**

| Name        | Type    | Description                           |
| ----------- | ------- | ------------------------------------- |
| `origin`    | address | Origin of the transaction (tx.origin) |
| `sender`    | address | Sender of the call (msg.sender)       |
| `token`     | address | Token address                         |
| `unitPrice` | uint256 | Unit price                            |

## VaultRegistry

*Inherits from* [*ERC721*](#erc721)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*ContractMeta*](#contractmeta)

⛽ 3.07M

This contract is used to manage ERC721 NFT for all Vaults.

### Functions

#### constructor

```solidity
  function constructor(string name, string symbol, contract IProtocolGovernance protocolGovernance_) public
```

Creates a new contract.

**Parameters:**

| Name                  | Type                         | Description                     |
| --------------------- | ---------------------------- | ------------------------------- |
| `name`                | string                       | ERC721 token name               |
| `symbol`              | string                       | ERC721 token symbol             |
| `protocolGovernance_` | contract IProtocolGovernance | Reference to ProtocolGovernance |

**Specs**

* ✅ creates VaultRegistry
* ✅ initializes ProtocolGovernance address
* ✅ initializes ERC721 token name
* ✅ initializes ERC721 token symbol

#### vaults

```solidity
  function vaults() external returns (address[])
```

**Specs**

* ✅ returns all registered vaults
* ✅ access control: allowed: any address
* ✅ ount returns the number of registered vaults
* ✅ ount access control: allowed: any address
* ✅ ount properties @property: when N new vaults have been registered, vaults count will be increased by N

#### vaultForNft

```solidity
  function vaultForNft(uint256 nft) external returns (address)
```

Get Vault for the giver NFT ID.

**Parameters:**

| Name    | Type    | Description |
| ------- | ------- | ----------- |
| `nftId` | uint256 | NFT ID      |

**Return Values:**

| Name    | Type    | Description                   |
| ------- | ------- | ----------------------------- |
| `vault` | address | Address of the Vault contract |

**Specs**

* ✅ resolves Vault address by VaultRegistry NFT
* ✅ access control: allowed: any address

*Edge cases*

* ✅ when Vault NFT is not registered in VaultRegistry returns zero address

#### nftForVault

```solidity
  function nftForVault(address vault) external returns (uint256)
```

Get NFT ID for given Vault contract address.

**Parameters:**

| Name    | Type    | Description                   |
| ------- | ------- | ----------------------------- |
| `vault` | address | Address of the Vault contract |

**Return Values:**

| Name    | Type    | Description |
| ------- | ------- | ----------- |
| `nftId` | uint256 | NFT ID      |

**Specs**

* ✅ resolves VaultRegistry NFT by Vault address
* ✅ access control: allowed: any address

*Edge cases*

* ✅ when Vault is not registered in VaultRegistry returns zero

#### isLocked

```solidity
  function isLocked(uint256 nft) external returns (bool)
```

Checks if the nft is locked for all transfers

**Parameters:**

| Name  | Type    | Description           |
| ----- | ------- | --------------------- |
| `nft` | uint256 | NFT to check for lock |

**Return Values:**

| Name | Type | Description             |
| ---- | ---- | ----------------------- |
| `if` | bool | locked, false otherwise |

**Specs**

* ✅ checks if token is locked (not transferable)
* ✅ access control: allowed: any address

*Edge cases*

* ✅ when VaultRegistry NFT is not registered in VaultRegistry returns false

#### protocolGovernance

```solidity
  function protocolGovernance() external returns (contract IProtocolGovernance)
```

Address of the ProtocolGovernance.

**Specs**

* ✅ returns ProtocolGovernance address
* ✅ access control: allowed: any address

#### stagedProtocolGovernance

```solidity
  function stagedProtocolGovernance() external returns (contract IProtocolGovernance)
```

Address of the staged ProtocolGovernance.

**Specs**

* ✅ returns ProtocolGovernance address staged for commit
* ✅ access control: allowed: any address
* ✅ imestamp returns timestamp after which #commitStagedProtocolGovernance can be called
* ✅ imestamp access control: allowed: any address
* ✅ imestamp edge cases when nothing is staged returns 0
* ✅ imestamp edge cases right after #commitStagedProtocolGovernance was called returns 0

*Edge cases*

* ✅ when nothing is staged returns zero address
* ✅ right after #commitStagedProtocolGovernance was called returns zero address

#### stagedProtocolGovernanceTimestamp

```solidity
  function stagedProtocolGovernanceTimestamp() external returns (uint256)
```

Minimal timestamp when staged ProtocolGovernance can be applied.

**Specs**

* ✅ returns timestamp after which #commitStagedProtocolGovernance can be called
* ✅ access control: allowed: any address

*Edge cases*

* ✅ when nothing is staged returns 0
* ✅ right after #commitStagedProtocolGovernance was called returns 0

#### vaultsCount

```solidity
  function vaultsCount() external returns (uint256)
```

Number of Vaults registered.

**Specs**

* ✅ returns the number of registered vaults
* ✅ access control: allowed: any address

*Properties*

* ✅ when N new vaults have been registered, vaults count will be increased by N

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

**Specs**

* ✅ returns true if this contract supports a certain interface
* ✅ access control: allowed: any address
* ✅ edge cases: when contract does not support the given interface returns false

#### registerVault

⛽ 167K (154K - 188K)

```solidity
  function registerVault(address vault, address owner) external returns (uint256 nft)
```

Register new Vault and mint NFT.

**Parameters:**

| Name    | Type    | Description          |
| ------- | ------- | -------------------- |
| `vault` | address | address of the vault |
| `owner` | address | owner of the NFT     |

**Return Values:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | Nft minted for the given Vault |

**Specs**

* ✅ binds minted ERC721 NFT to Vault address and transfers minted NFT to owner specified in args
* ✅ emits VaultRegistered event
* ✅ access control: allowed: any account with Register Vault permissions
* ✅ access control: denied: any other address
* ✅ access control: denied: protocol governance admin

*Properties*

* ✅ minted NFT equals to vaultRegistry#vaultsCount

*Edge cases*

* ✅ when address doesn't conform to IVault interface (IERC165) reverts with INVI
* ✅ when vault has already been registered reverts with DUP
* ✅ when owner address is zero reverts with AZ

#### stageProtocolGovernance

⛽ 75K (43K - 80K)

```solidity
  function stageProtocolGovernance(contract IProtocolGovernance newProtocolGovernance) external
```

Stage new ProtocolGovernance.

**Parameters:**

| Name                    | Type                         | Description            |
| ----------------------- | ---------------------------- | ---------------------- |
| `newProtocolGovernance` | contract IProtocolGovernance | new ProtocolGovernance |

**Specs**

* ✅ stages new ProtocolGovernance for commit
* ✅ sets the stagedProtocolGovernanceTimestamp after which #commitStagedProtocolGovernance can be called
* ✅ access control: allowed: ProtocolGovernance Admin
* ✅ access control: denied: any other address
* ✅ access control: denied: deployer

*Edge cases*

* ✅ when new ProtocolGovernance is a zero address reverts with AZ

#### commitStagedProtocolGovernance

⛽ 34K

```solidity
  function commitStagedProtocolGovernance() external
```

Commit new ProtocolGovernance.

**Specs**

* ✅ commits staged ProtocolGovernance
* ✅ resets staged ProtocolGovernanceTimestamp
* ✅ resets staged ProtocolGovernance
* ✅ access control: allowed: ProtocolGovernance Admin
* ✅ access control: denied: any other address

*Edge cases*

* ✅ when nothing is staged reverts with INIT
* ✅ when called before stagedProtocolGovernanceTimestamp reverts with TS
* ✅ when called before stagedProtocolGovernanceTimestamp reverts with TS

#### lockNft

⛽ 46K (29K - 49K)

```solidity
  function lockNft(uint256 nft) external
```

**Specs**

* ✅ locks NFT (disables any transfer)
* ✅ emits TokenLocked event
* ✅ access control: allowed: NFT owner
* ✅ access control: denied: any other address
* ✅ access control: denied: protocol admin

*Edge cases*

* ✅ when NFT has already been locked succeeds

### Events

#### TokenLocked

```solidity
  event TokenLocked(address origin, address sender, uint256 nft)
```

Emitted when token is locked for transfers

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |
| `nft`    | uint256 | NFT to be locked                      |

#### VaultRegistered

```solidity
  event VaultRegistered(address origin, address sender, uint256 nft, address vault, address owner)
```

Emitted when new Vault is registered in VaultRegistry

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |
| `nft`    | uint256 | VaultRegistry NFT of the vault        |
| `vault`  | address | Address of the Vault contract         |
| `owner`  | address | Owner of the VaultRegistry NFT        |

#### StagedProtocolGovernance

```solidity
  event StagedProtocolGovernance(address origin, address sender, contract IProtocolGovernance newProtocolGovernance, uint256 start)
```

**Parameters:**

| Name                    | Type                         | Description                                          |
| ----------------------- | ---------------------------- | ---------------------------------------------------- |
| `origin`                | address                      | Origin of the transaction (tx.origin)                |
| `sender`                | address                      | Sender of the call (msg.sender)                      |
| `newProtocolGovernance` | contract IProtocolGovernance | Address of the new ProtocolGovernance                |
| `start`                 | uint256                      | Timestamp of the start of the new ProtocolGovernance |

#### CommitedProtocolGovernance

```solidity
  event CommitedProtocolGovernance(address origin, address sender, contract IProtocolGovernance newProtocolGovernance)
```

**Parameters:**

| Name                    | Type                         | Description                                                   |
| ----------------------- | ---------------------------- | ------------------------------------------------------------- |
| `origin`                | address                      | Origin of the transaction (tx.origin)                         |
| `sender`                | address                      | Sender of the call (msg.sender)                               |
| `newProtocolGovernance` | contract IProtocolGovernance | Address of the new ProtocolGovernance that has been committed |

## CommonLibrary

CommonLibrary shared utilities

## ExceptionsLibrary

Exceptions stores project\`s smart-contracts exceptions

## PermissionIdsLibrary

Stores permission ids for addresses

## SemverLibrary

## ChainlinkOracle

*Inherits from* [*DefaultAccessControl*](#defaultaccesscontrol)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*ContractMeta*](#contractmeta)

⛽ 2.77M

Contract for getting chainlink data

### Functions

#### constructor

```solidity
  function constructor(address[] tokens, address[] oracles, address admin) public
```

#### hasOracle

```solidity
  function hasOracle(address token) external returns (bool)
```

Checks if token has chainlink oracle

**Parameters:**

| Name    | Type    | Description   |
| ------- | ------- | ------------- |
| `token` | address | token address |

**Return Values:**

| Name | Type | Description                   |
| ---- | ---- | ----------------------------- |
| `if` | bool | token is allowed, `false` o/w |

**Specs**

* ✅ returns true if oracle is supported
* ✅ edge cases: when oracle is not supported returns false

#### supportedTokens

```solidity
  function supportedTokens() external returns (address[])
```

A list of supported tokens

**Specs**

* ✅ returns list of supported tokens

#### priceX96

```solidity
  function priceX96(address token0, address token1, uint256 safetyIndicesSet) external returns (uint256[] pricesX96, uint256[] safetyIndices)
```

Oracle price for tokens as a Q64.96 value. Returns pricing information based on the indexes of non-zero bits in safetyIndicesSet. It is possible that not all indices will have their respective prices returned.

📕 The price is token1 / token0 i.e. how many weis of token1 required for 1 wei of token0. The safety indexes are:

1 - unsafe, this is typically a spot price that can be easily manipulated,

2 - 4 - more or less safe, this is typically a uniV3 oracle, where the safety is defined by the timespan of the average price

5 - safe - this is typically a chailink oracle

**Parameters:**

| Name               | Type    | Description                                                                                                                 |
| ------------------ | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| `token0`           | address | Reference to token0                                                                                                         |
| `token1`           | address | Reference to token1                                                                                                         |
| `safetyIndicesSet` | uint256 | Bitmask of safety indices that are allowed for the return prices. For set of safety indexes = { 1 }, safetyIndicesSet = 0x2 |

**Return Values:**

| Name            | Type       | Description                                |
| --------------- | ---------- | ------------------------------------------ |
| `pricesX96`     | uint256\[] | Prices that satisfy safetyIndex and tokens |
| `safetyIndices` | uint256\[] | Safety indices for those prices            |

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true for ChainlinkOracle interface (0x8e3bd5d7)
* ✅ edge cases: when contract does not support the given interface returns false

#### addChainlinkOracles

⛽ 82K (81K - 83K)

```solidity
  function addChainlinkOracles(address[] tokens, address[] oracles) external
```

Add a Chainlink price feed for a token

**Parameters:**

| Name      | Type       | Description                                |
| --------- | ---------- | ------------------------------------------ |
| `tokens`  | address\[] | ERC20 tokens for the feed                  |
| `oracles` | address\[] | Chainlink oracle price feeds (token / USD) |

**Specs**

* ✅ emits OraclesAdded event
* ✅ when oracles have set by addChainLinkOracles function returns prices
* ✅ edge cases: when arrays have different lengths reverts with INV
* ✅ edge cases: when sender has no admin righs reverts with FRB

### Structs

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### OraclesAdded

```solidity
  event OraclesAdded(address origin, address sender, address[] tokens, address[] oracles)
```

Emitted when new Chainlink oracle is added

**Parameters:**

| Name      | Type       | Description                           |
| --------- | ---------- | ------------------------------------- |
| `origin`  | address    | Origin of the transaction (tx.origin) |
| `sender`  | address    | Sender of the call (msg.sender)       |
| `tokens`  | address\[] | Tokens added                          |
| `oracles` | address\[] | Orecles added for the tokens          |

## MellowOracle

*Inherits from* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 783K

#### constructor

```solidity
  function constructor(contract IUniV2Oracle univ2Oracle_, contract IUniV3Oracle univ3Oracle_, contract IChainlinkOracle chainlinkOracle_) public
```

#### priceX96

```solidity
  function priceX96(address token0, address token1, uint256 safetyIndicesSet) external returns (uint256[] pricesX96, uint256[] safetyIndices)
```

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true for IUniV3Oracle interface (0x6d80125b)
* ✅ edge cases: when contract does not support the given interface returns false

## UniV2Oracle

*Inherits from* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 671K

#### constructor

```solidity
  function constructor(contract IUniswapV2Factory factory_) public
```

#### priceX96

```solidity
  function priceX96(address token0, address token1, uint256 safetyIndicesSet) external returns (uint256[] pricesX96, uint256[] safetyIndices)
```

Oracle price for tokens as a Q64.96 value. Returns pricing information based on the indexes of non-zero bits in safetyIndicesSet. It is possible that not all indices will have their respective prices returned.

📕 The price is token1 / token0 i.e. how many weis of token1 required for 1 wei of token0. The safety indexes are:

1 - unsafe, this is typically a spot price that can be easily manipulated,

2 - 4 - more or less safe, this is typically a uniV3 oracle, where the safety is defined by the timespan of the average price

5 - safe - this is typically a chailink oracle

**Parameters:**

| Name               | Type    | Description                                                                                                                 |
| ------------------ | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| `token0`           | address | Reference to token0                                                                                                         |
| `token1`           | address | Reference to token1                                                                                                         |
| `safetyIndicesSet` | uint256 | Bitmask of safety indices that are allowed for the return prices. For set of safety indexes = { 1 }, safetyIndicesSet = 0x2 |

**Return Values:**

| Name            | Type       | Description                                |
| --------------- | ---------- | ------------------------------------------ |
| `pricesX96`     | uint256\[] | Prices that satisfy safetyIndex and tokens |
| `safetyIndices` | uint256\[] | Safety indices for those prices            |

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true for IUniV2Oracle interface (0x2748645e)
* ✅ edge cases: when contract does not support the given interface returns false

## UniV3Oracle

*Inherits from* [*DefaultAccessControl*](#defaultaccesscontrol)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*ContractMeta*](#contractmeta)

⛽ 3.44M

### Functions

#### constructor

```solidity
  function constructor(contract IUniswapV3Factory factory_, contract IUniswapV3Pool[] pools, address admin) public
```

#### priceX96

```solidity
  function priceX96(address token0, address token1, uint256 safetyIndicesSet) external returns (uint256[] pricesX96, uint256[] safetyIndices)
```

Oracle price for tokens as a Q64.96 value. Returns pricing information based on the indexes of non-zero bits in safetyIndicesSet. It is possible that not all indices will have their respective prices returned.

📕 Logic of this function is next: If there is no initialized pool for the passed tokens, empty arrays will be returned. Depending on safetyIndicesSet if the 1st bit in safetyIndicesSet is non-zero, then the response will contain the spot price. If there is a non-zero 2nd bit in the safetyIndicesSet and the corresponding position in the pool was created no later than LOW\_OBS\_DELTA seconds ago, then the average price for the last LOW\_OBS\_DELTA seconds will be returned. The same logic exists for the 3rd and MID\_OBS\_DELTA, and 4th index and HIGH\_OBS\_DELTA.

**Parameters:**

| Name               | Type    | Description                                                                                                                 |
| ------------------ | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| `token0`           | address | Reference to token0                                                                                                         |
| `token1`           | address | Reference to token1                                                                                                         |
| `safetyIndicesSet` | uint256 | Bitmask of safety indices that are allowed for the return prices. For set of safety indexes = { 1 }, safetyIndicesSet = 0x2 |

**Return Values:**

| Name            | Type       | Description                                |
| --------------- | ---------- | ------------------------------------------ |
| `pricesX96`     | uint256\[] | Prices that satisfy safetyIndex and tokens |
| `safetyIndices` | uint256\[] | Safety indices for those prices            |

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true for IUniV3Oracle interface (0x2a3602d6)
* ✅ when contract does not support the given interface returns false

#### addUniV3Pools

⛽ 73K (39K - 89K)

```solidity
  function addUniV3Pools(contract IUniswapV3Pool[] pools) external
```

Add UniV3 pools for prices.

**Parameters:**

| Name    | Type                       | Description  |
| ------- | -------------------------- | ------------ |
| `pools` | contract IUniswapV3Pool\[] | Pools to add |

**Specs**

* ✅ when adding \[weth, usdc] pools with fee = 500 adds pools
* ✅ when adding \[weth, usdc] pools with fee = 3000 adds pools
* ✅ when adding \[weth, usdc] pools with fee = 10000 does not return prices

### Structs

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### PoolsUpdated

```solidity
  event PoolsUpdated(address origin, address sender, contract IUniswapV3Pool[] pools, contract IUniswapV3Pool[] replacedPools)
```

Emitted when new pool is added or updated and become available for oracle prices

**Parameters:**

| Name            | Type                       | Description                           |
| --------------- | -------------------------- | ------------------------------------- |
| `origin`        | address                    | Origin of the transaction (tx.origin) |
| `sender`        | address                    | Sender of the call (msg.sender)       |
| `pools`         | contract IUniswapV3Pool\[] | UniV3 pools added                     |
| `replacedPools` | contract IUniswapV3Pool\[] | UniV3 pools updated                   |

## HStrategy

*Inherits from* [*DefaultAccessControlLateInit*](#defaultaccesscontrollateinit)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*Multicall*](#multicall)*,* [*ContractMeta*](#contractmeta)

⛽ 7.59M

### Functions

#### constructor

```solidity
  function constructor(contract INonfungiblePositionManager positionManager_, contract ISwapRouter router_, address uniV3Helper_, address hStrategyHelper_) public
```

constructs a strategy

**Parameters:**

| Name               | Type                                 | Description                                  |
| ------------------ | ------------------------------------ | -------------------------------------------- |
| `positionManager_` | contract INonfungiblePositionManager | the position manager for uniV3               |
| `router_`          | contract ISwapRouter                 | the uniV3 router for swapping tokens         |
| `uniV3Helper_`     | address                              | the address of the helper contract for uniV3 |
| `hStrategyHelper_` | address                              | the address of the strategy helper contract  |

**Specs**

* ✅ deploys a new contract

#### initialize

```solidity
  function initialize(address[] tokens_, contract IERC20Vault erc20Vault_, contract IIntegrationVault moneyVault_, contract IUniV3Vault uniV3Vault_, uint24 fee_, address admin_) external
```

initializes the strategy

**Parameters:**

| Name          | Type                       | Description                                                        |
| ------------- | -------------------------- | ------------------------------------------------------------------ |
| `tokens_`     | address\[]                 | the addresses of the tokens managed by the strategy                |
| `erc20Vault_` | contract IERC20Vault       | the address of the erc20 vault                                     |
| `moneyVault_` | contract IIntegrationVault | the address of the moneyVault. It is expected to be yEarn or AAVE  |
| `uniV3Vault_` | contract IUniV3Vault       | the address of uniV3Vault. It is expected to not hold the position |
| `fee_`        | uint24                     | the fee of the uniV3 pool on which the vault operates              |
| `admin_`      | address                    | the addres of the admin of the strategy                            |

#### createStrategy

⛽ 536K (536K - 539K)

```solidity
  function createStrategy(address[] tokens_, contract IERC20Vault erc20Vault_, contract IIntegrationVault moneyVault_, contract IUniV3Vault uniV3Vault_, uint24 fee_, address admin_) external returns (contract HStrategy strategy)
```

creates the clone of the strategy

**Parameters:**

| Name          | Type                       | Description                                                        |
| ------------- | -------------------------- | ------------------------------------------------------------------ |
| `tokens_`     | address\[]                 | the addresses of the tokens managed by the strategy                |
| `erc20Vault_` | contract IERC20Vault       | the address of the erc20 vault                                     |
| `moneyVault_` | contract IIntegrationVault | the address of the moneyVault. It is expected to be yEarn or AAVE  |
| `uniV3Vault_` | contract IUniV3Vault       | the address of uniV3Vault. It is expected to not hold the position |
| `fee_`        | uint24                     | the fee of the uniV3 pool on which the vault operates              |
| `admin_`      | address                    | the addres of the admin of the strategy                            |

**Return Values:**

| Name       | Type               | Description                 |
| ---------- | ------------------ | --------------------------- |
| `strategy` | contract HStrategy | the address of new strategy |

**Specs**

* ✅ creates a new strategy and initializes it

#### updateStrategyParams

⛽ 48K (44K - 51K)

```solidity
  function updateStrategyParams(struct HStrategy.StrategyParams newStrategyParams) external
```

updates parameters of the strategy. Can be called only by admin

**Parameters:**

| Name                | Type                            | Description        |
| ------------------- | ------------------------------- | ------------------ |
| `newStrategyParams` | struct HStrategy.StrategyParams | the new parameters |

#### updateMintingParams

```solidity
  function updateMintingParams(struct HStrategy.MintingParams newMintingParams) external
```

updates parameters for minting position. Can be called only by admin

**Parameters:**

| Name               | Type                           | Description        |
| ------------------ | ------------------------------ | ------------------ |
| `newMintingParams` | struct HStrategy.MintingParams | the new parameters |

#### updateOracleParams

```solidity
  function updateOracleParams(struct HStrategy.OracleParams newOracleParams) external
```

updates oracle parameters. Can be called only by admin

**Parameters:**

| Name              | Type                          | Description        |
| ----------------- | ----------------------------- | ------------------ |
| `newOracleParams` | struct HStrategy.OracleParams | the new parameters |

#### updateRatioParams

⛽ 39K (38K - 40K)

```solidity
  function updateRatioParams(struct HStrategy.RatioParams newRatioParams) external
```

updates parameters of the capital ratios and deviation. Can be called only by admin

**Parameters:**

| Name             | Type                         | Description        |
| ---------------- | ---------------------------- | ------------------ |
| `newRatioParams` | struct HStrategy.RatioParams | the new parameters |

#### updateSwapFees

```solidity
  function updateSwapFees(uint24 newSwapFees) external
```

updates swap fees for uniswapV3Pool swaps

**Parameters:**

| Name          | Type   | Description        |
| ------------- | ------ | ------------------ |
| `newSwapFees` | uint24 | the new parameters |

#### manualPull

⛽ 468K (256K - 517K)

```solidity
  function manualPull(contract IIntegrationVault fromVault, contract IIntegrationVault toVault, uint256[] tokenAmounts, bytes vaultOptions) external
```

manual pulling tokens from vault. Can be called only by admin

**Parameters:**

| Name           | Type                       | Description                                  |
| -------------- | -------------------------- | -------------------------------------------- |
| `fromVault`    | contract IIntegrationVault | the address of the vault to pull tokens from |
| `toVault`      | contract IIntegrationVault | the address of the vault to pull tokens to   |
| `tokenAmounts` | uint256\[]                 | the amount of tokens to be pulled            |
| `vaultOptions` | bytes                      | additional options for `pull` method         |

**Specs**

* ✅ pulls token amounts from fromVault to toVault

#### rebalance

⛽ 1.44M (352K - 1.75M)

```solidity
  function rebalance(struct HStrategy.RebalanceTokenAmounts restrictions, bytes moneyVaultOptions) external returns (struct HStrategy.RebalanceTokenAmounts actualPulledAmounts, uint256[] burnedAmounts)
```

rebalance method. Need to be called if the new position is needed

**Parameters:**

| Name                | Type                                   | Description                                                         |
| ------------------- | -------------------------------------- | ------------------------------------------------------------------- |
| `restrictions`      | struct HStrategy.RebalanceTokenAmounts | the restrictions of the amount of tokens to be transferred          |
| `moneyVaultOptions` | bytes                                  | additional parameters for pulling for `pull` method for money vault |

**Return Values:**

| Name                  | Type                                   | Description                               |
| --------------------- | -------------------------------------- | ----------------------------------------- |
| `actualPulledAmounts` | struct HStrategy.RebalanceTokenAmounts | actual transferred amounts                |
| `burnedAmounts`       | uint256\[]                             | actual burned amounts from uniV3 position |

**Specs**

* ✅ performs a rebalance according to strategy params

### Structs

```solidity
struct StrategyParams {
    int24 halfOfShortInterval;
    int24 tickNeighborhood;
    int24 domainLowerTick;
    int24 domainUpperTick;
}
```

```solidity
struct MintingParams {
    uint256 minToken0ForOpening;
    uint256 minToken1ForOpening;
}
```

```solidity
struct OracleParams {
    uint32 averagePriceTimeSpan;
    uint24 maxTickDeviation;
}
```

```solidity
struct RatioParams {
    uint256 erc20CapitalRatioD;
    uint256 minCapitalDeviationD;
    uint256 minRebalanceDeviationD;
}
```

```solidity
struct Interval {
    int24 lowerTick;
    int24 upperTick;
}
```

```solidity
struct RebalanceTokenAmounts {
    uint256[] pulledToUniV3Vault;
    uint256[] pulledFromUniV3Vault;
    int256[] swappedAmounts;
    uint256[] burnedAmounts;
    uint256 deadline;
}
```

```solidity
struct TokenAmountsInToken0 {
    uint256 erc20TokensAmountInToken0;
    uint256 moneyTokensAmountInToken0;
    uint256 uniV3TokensAmountInToken0;
    uint256 totalTokensInToken0;
}
```

```solidity
struct TokenAmounts {
    uint256 erc20Token0;
    uint256 erc20Token1;
    uint256 moneyToken0;
    uint256 moneyToken1;
    uint256 uniV3Token0;
    uint256 uniV3Token1;
}
```

```solidity
struct ExpectedRatios {
    uint32 token0RatioD;
    uint32 token1RatioD;
    uint32 uniV3RatioD;
}
```

```solidity
struct DomainPositionParams {
    uint256 nft;
    uint128 liquidity;
    int24 lowerTick;
    int24 upperTick;
    int24 domainLowerTick;
    int24 domainUpperTick;
    uint160 lowerPriceSqrtX96;
    uint160 upperPriceSqrtX96;
    uint160 domainLowerPriceSqrtX96;
    uint160 domainUpperPriceSqrtX96;
    uint160 intervalPriceSqrtX96;
    uint256 spotPriceX96;
}
```

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### MintUniV3Position

```solidity
  event MintUniV3Position(uint256 uniV3Nft, int24 lowerTick, int24 upperTick)
```

Emitted when new position in UniV3Pool has been minted.

**Parameters:**

| Name        | Type    | Description                |
| ----------- | ------- | -------------------------- |
| `uniV3Nft`  | uint256 | nft of new minted position |
| `lowerTick` | int24   | lowerTick of that position |
| `upperTick` | int24   | upperTick of that position |

#### BurnUniV3Position

```solidity
  event BurnUniV3Position(uint256 uniV3Nft)
```

Emitted when position in UniV3Pool has been burnt.

**Parameters:**

| Name       | Type    | Description                |
| ---------- | ------- | -------------------------- |
| `uniV3Nft` | uint256 | nft of new minted position |

#### SwapTokensOnERC20Vault

```solidity
  event SwapTokensOnERC20Vault(address origin, struct ISwapRouter.ExactInputSingleParams swapParams)
```

Emitted when swap is initiated.

**Parameters:**

| Name         | Type                                      | Description                           |
| ------------ | ----------------------------------------- | ------------------------------------- |
| `origin`     | address                                   | Origin of the transaction (tx.origin) |
| `swapParams` | struct ISwapRouter.ExactInputSingleParams | Swap domainPositionParams             |

#### UpdateStrategyParams

```solidity
  event UpdateStrategyParams(address origin, address sender, struct HStrategy.StrategyParams strategyParams)
```

Emitted when Strategy strategyParams are set.

**Parameters:**

| Name             | Type                            | Description                           |
| ---------------- | ------------------------------- | ------------------------------------- |
| `origin`         | address                         | Origin of the transaction (tx.origin) |
| `sender`         | address                         | Sender of the call (msg.sender)       |
| `strategyParams` | struct HStrategy.StrategyParams | Updated strategyParams                |

#### UpdateMintingParams

```solidity
  event UpdateMintingParams(address origin, address sender, struct HStrategy.MintingParams mintingParams)
```

Emitted when Strategy mintingParams are set.

**Parameters:**

| Name            | Type                           | Description                           |
| --------------- | ------------------------------ | ------------------------------------- |
| `origin`        | address                        | Origin of the transaction (tx.origin) |
| `sender`        | address                        | Sender of the call (msg.sender)       |
| `mintingParams` | struct HStrategy.MintingParams | Updated mintingParams                 |

#### UpdateOracleParams

```solidity
  event UpdateOracleParams(address origin, address sender, struct HStrategy.OracleParams oracleParams)
```

Emitted when Strategy oracleParams are set.

**Parameters:**

| Name           | Type                          | Description                           |
| -------------- | ----------------------------- | ------------------------------------- |
| `origin`       | address                       | Origin of the transaction (tx.origin) |
| `sender`       | address                       | Sender of the call (msg.sender)       |
| `oracleParams` | struct HStrategy.OracleParams | Updated oracleParams                  |

#### UpdateRatioParams

```solidity
  event UpdateRatioParams(address origin, address sender, struct HStrategy.RatioParams ratioParams)
```

Emitted when Strategy ratioParams are set.

**Parameters:**

| Name          | Type                         | Description                           |
| ------------- | ---------------------------- | ------------------------------------- |
| `origin`      | address                      | Origin of the transaction (tx.origin) |
| `sender`      | address                      | Sender of the call (msg.sender)       |
| `ratioParams` | struct HStrategy.RatioParams | Updated ratioParams                   |

#### UpdateSwapFees

```solidity
  event UpdateSwapFees(address origin, address sender, uint24 newSwapFees)
```

Emitted when new swap fees for UniV3Pool swaps are set.

**Parameters:**

| Name          | Type    | Description                           |
| ------------- | ------- | ------------------------------------- |
| `newSwapFees` | address | new swap fee                          |
| `origin`      | address | Origin of the transaction (tx.origin) |
| `sender`      | uint24  | Sender of the call (msg.sender)       |

## LStrategy

*Inherits from* [*DefaultAccessControl*](#defaultaccesscontrol)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)

⛽ 7.65M

### Functions

#### constructor

```solidity
  function constructor(contract INonfungiblePositionManager positionManager_, address cowswapSettlement_, address cowswapVaultRelayer_, contract IERC20Vault erc20vault_, contract IUniV3Vault vault1_, contract IUniV3Vault vault2_, contract ILStrategyHelper orderHelper_, address admin_, uint16 intervalWidthInTicks_) public
```

#### getTargetPriceX96

```solidity
  function getTargetPriceX96(address token0, address token1, struct LStrategy.TradingParams tradingParams_) public returns (uint256 priceX96)
```

Target price based on mutable params, as a Q64.96 value

#### targetUniV3LiquidityRatio

```solidity
  function targetUniV3LiquidityRatio(int24 targetTick_) public returns (uint128 liquidityRatioD, bool isNegative)
```

Target liquidity ratio for UniV3 vaults

#### rebalanceERC20UniV3Vaults

⛽ 505K (326K - 1.69M)

```solidity
  function rebalanceERC20UniV3Vaults(uint256[] minLowerVaultTokens, uint256[] minUpperVaultTokens, uint256 deadline) public returns (uint256[] totalPulledAmounts, bool isNegativeCapitalDelta, uint256 percentageIncreaseD)
```

Make a rebalance between ERC20 and UniV3 Vaults

**Parameters:**

| Name                  | Type       | Description                                   |
| --------------------- | ---------- | --------------------------------------------- |
| `minLowerVaultTokens` | uint256\[] | Min accepted tokenAmounts for lower vault     |
| `minUpperVaultTokens` | uint256\[] | Min accepted tokenAmounts for upper vault     |
| `deadline`            | uint256    | Timestamp after which the transaction reverts |

**Return Values:**

| Name                     | Type       | Description                                            |
| ------------------------ | ---------- | ------------------------------------------------------ |
| `totalPulledAmounts`     | uint256\[] | total amounts pulled from erc20 vault or Uni vaults    |
| `isNegativeCapitalDelta` | bool       | `true` if rebalance if from UniVaults, false otherwise |
| `percentageIncreaseD`    | uint256    | the percentage of capital change of UniV3 vaults       |

#### rebalanceUniV3Vaults

⛽ 432K (138K - 900K)

```solidity
  function rebalanceUniV3Vaults(uint256[] minWithdrawTokens, uint256[] minDepositTokens, uint256 deadline) external returns (uint256[] pulledAmounts, uint256[] pushedAmounts, uint128 depositLiquidity, uint128 withdrawLiquidity, bool lowerToUpper)
```

Make a rebalance of UniV3 vaults

**Parameters:**

| Name                | Type       | Description                                   |
| ------------------- | ---------- | --------------------------------------------- |
| `minWithdrawTokens` | uint256\[] | Min accepted tokenAmounts for withdrawal      |
| `minDepositTokens`  | uint256\[] | Min accepted tokenAmounts for deposit         |
| `deadline`          | uint256    | Timestamp after which the transaction reverts |

**Return Values:**

| Name                | Type       | Description                                          |
| ------------------- | ---------- | ---------------------------------------------------- |
| `pulledAmounts`     | uint256\[] | Amounts pulled from one vault                        |
| `pushedAmounts`     | uint256\[] | Amounts pushed to the other vault                    |
| `depositLiquidity`  | uint128    | Amount of liquidity deposited to vault               |
| `withdrawLiquidity` | uint128    | Amount of liquidity withdrawn from vault             |
| `lowerToUpper`      | bool       | true if liquidity is moved from lower vault to upper |

#### postPreOrder

⛽ 144K (140K - 180K)

```solidity
  function postPreOrder(uint256 minAmountOut) external returns (struct LStrategy.PreOrder preOrder_)
```

Post preorder for ERC20 vault rebalance.

**Parameters:**

| Name           | Type    | Description                          |
| -------------- | ------- | ------------------------------------ |
| `minAmountOut` | uint256 | minimum amount out of tokens to swap |

**Return Values:**

| Name        | Type                      | Description     |
| ----------- | ------------------------- | --------------- |
| `preOrder_` | struct LStrategy.PreOrder | Posted preorder |

#### signOrder

⛽ 210K (103K - 233K)

```solidity
  function signOrder(struct GPv2Order.Data order, bytes uuid, bool signed) external
```

Sign offchain cowswap order onchain

**Parameters:**

| Name     | Type                  | Description                 |
| -------- | --------------------- | --------------------------- |
| `order`  | struct GPv2Order.Data | Cowswap order data          |
| `uuid`   | bytes                 | Cowswap order id            |
| `signed` | bool                  | To sign order set to `true` |

#### resetCowswapAllowance

⛽ 117K (116K - 118K)

```solidity
  function resetCowswapAllowance(uint8 tokenNumber) external
```

Reset cowswap allowance to 0

**Parameters:**

| Name          | Type  | Description                      |
| ------------- | ----- | -------------------------------- |
| `tokenNumber` | uint8 | The number of token in LStrategy |

#### collectUniFees

⛽ 279K (239K - 320K)

```solidity
  function collectUniFees() external returns (uint256[] totalCollectedEarnings)
```

Collect Uniswap pool fees to erc20 vault

**Return Values:**

| Name                     | Type       | Description          |
| ------------------------ | ---------- | -------------------- |
| `totalCollectedEarnings` | uint256\[] | Total collected fees |

#### manualPull

⛽ 345K (297K - 487K)

```solidity
  function manualPull(contract IIntegrationVault fromVault, contract IIntegrationVault toVault, uint256[] tokenAmounts, uint256[] minTokensAmounts, uint256 deadline) external returns (uint256[] actualTokenAmounts)
```

Manually pull tokens from fromVault to toVault

**Parameters:**

| Name               | Type                       | Description                                      |
| ------------------ | -------------------------- | ------------------------------------------------ |
| `fromVault`        | contract IIntegrationVault | Pull tokens from this vault                      |
| `toVault`          | contract IIntegrationVault | Pull tokens to this vault                        |
| `tokenAmounts`     | uint256\[]                 | Token amounts to pull                            |
| `minTokensAmounts` | uint256\[]                 | Minimal token amounts to pull                    |
| `deadline`         | uint256                    | Timestamp after which the transaction is invalid |

#### updateTradingParams

⛽ 68K (42K - 119K)

```solidity
  function updateTradingParams(struct LStrategy.TradingParams newTradingParams) external
```

Sets new trading params

**Parameters:**

| Name               | Type                           | Description                   |
| ------------------ | ------------------------------ | ----------------------------- |
| `newTradingParams` | struct LStrategy.TradingParams | New trading parameters to set |

#### updateRatioParams

⛽ 37K (36K - 53K)

```solidity
  function updateRatioParams(struct LStrategy.RatioParams newRatioParams) external
```

Sets new ratio params

**Parameters:**

| Name             | Type                         | Description                 |
| ---------------- | ---------------------------- | --------------------------- |
| `newRatioParams` | struct LStrategy.RatioParams | New ratio parameters to set |

#### updateOtherParams

⛽ 41K (33K - 94K)

```solidity
  function updateOtherParams(struct LStrategy.OtherParams newOtherParams) external
```

Sets new other params

**Parameters:**

| Name             | Type                         | Description                 |
| ---------------- | ---------------------------- | --------------------------- |
| `newOtherParams` | struct LStrategy.OtherParams | New other parameters to set |

### Structs

```solidity
struct TradingParams {
    IOracle oracle;
    uint32 maxSlippageD;
    uint32 orderDeadline;
    uint256 oracleSafetyMask;
    uint256 maxFee0;
    uint256 maxFee1;
}
```

```solidity
struct RatioParams {
    uint32 erc20UniV3CapitalRatioD;
    uint32 erc20TokenRatioD;
    uint32 minErc20UniV3CapitalRatioDeviationD;
    uint32 minErc20TokenRatioDeviationD;
    uint32 minUniV3LiquidityRatioDeviationD;
}
```

```solidity
struct OtherParams {
    uint256 minToken0ForOpening;
    uint256 minToken1ForOpening;
    uint256 secondsBetweenRebalances;
}
```

```solidity
struct PreOrder {
    address tokenIn;
    address tokenOut;
    uint64 deadline;
    uint256 amountIn;
    uint256 minAmountOut;
}
```

```solidity
struct LiquidityParams {
    uint128 targetUniV3LiquidityRatioD;
    bool isNegativeLiquidityRatio;
}
```

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### PreOrderPosted

```solidity
  event PreOrderPosted(address origin, address sender, struct LStrategy.PreOrder preOrder)
```

Emitted when a new cowswap preOrder is posted.

**Parameters:**

| Name       | Type                      | Description                           |
| ---------- | ------------------------- | ------------------------------------- |
| `origin`   | address                   | Origin of the transaction (tx.origin) |
| `sender`   | address                   | Sender of the call (msg.sender)       |
| `preOrder` | struct LStrategy.PreOrder | Preorder that was posted              |

#### OrderSigned

```solidity
  event OrderSigned(address origin, address sender, bytes uuid, struct GPv2Order.Data order, struct LStrategy.PreOrder preOrder, bool signed)
```

Emitted when cowswap preOrder was signed onchain.

**Parameters:**

| Name       | Type                      | Description                           |
| ---------- | ------------------------- | ------------------------------------- |
| `origin`   | address                   | Origin of the transaction (tx.origin) |
| `sender`   | address                   | Sender of the call (msg.sender)       |
| `order`    | bytes                     | Cowswap order                         |
| `preOrder` | struct GPv2Order.Data     | PreOrder that the order fulfills      |
| `signed`   | struct LStrategy.PreOrder | Singned or unsigned                   |

#### ManualPull

```solidity
  event ManualPull(address origin, address sender, uint256[] tokenAmounts, uint256[] actualTokenAmounts)
```

Emitted when manual pull from vault is executed.

**Parameters:**

| Name           | Type       | Description                           |
| -------------- | ---------- | ------------------------------------- |
| `origin`       | address    | Origin of the transaction (tx.origin) |
| `sender`       | address    | Sender of the call (msg.sender)       |
| `tokenAmounts` | uint256\[] | The amounts of tokens that were       |

#### SwapVault

```solidity
  event SwapVault(uint256 oldNft, uint256 newNft, int24 newTickLower, int24 newTickUpper)
```

Emitted when vault is swapped.

**Parameters:**

| Name           | Type    | Description                      |
| -------------- | ------- | -------------------------------- |
| `oldNft`       | uint256 | UniV3 nft that was burned        |
| `newNft`       | uint256 | UniV3 nft that was created       |
| `newTickLower` | int24   | Lower tick for created UniV3 nft |
| `newTickUpper` | int24   | Upper tick for created UniV3 nft |

#### RebalancedErc20UniV3

```solidity
  event RebalancedErc20UniV3(address origin, address sender, bool fromErc20, uint256[] pulledAmounts)
```

Emitted when rebalance from UniV3 to ERC20 or vice versa happens

**Parameters:**

| Name            | Type       | Description                           |
| --------------- | ---------- | ------------------------------------- |
| `origin`        | address    | Origin of the transaction (tx.origin) |
| `sender`        | address    | Sender of the call (msg.sender)       |
| `fromErc20`     | bool       | `true` if the rebalance is made       |
| `pulledAmounts` | uint256\[] | amounts pulled from fromVault         |

#### RebalancedUniV3

```solidity
  event RebalancedUniV3(address origin, address sender, address fromVault, address toVault, uint256[] pulledAmounts, uint256[] pushedAmounts, uint128 desiredLiquidity, uint128 liquidity)
```

**Parameters:**

| Name               | Type       | Description                                                                                                                            |
| ------------------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `fromVault`        | address    | The vault to pull liquidity from                                                                                                       |
| `toVault`          | address    | The vault to pull liquidity to                                                                                                         |
| `pulledAmounts`    | address    | amounts pulled from fromVault                                                                                                          |
| `pushedAmounts`    | address    | amounts pushed to toVault                                                                                                              |
| `desiredLiquidity` | uint256\[] | The amount of liquidity desired for rebalance. This could be cut to available erc20 vault balance and available uniV3 vault liquidity. |
| `liquidity`        | uint256\[] | The actual amount of liquidity rebalanced.                                                                                             |

#### TradingParamsUpdated

```solidity
  event TradingParamsUpdated(address origin, address sender, struct LStrategy.TradingParams tradingParams)
```

Emitted when trading params were updated

**Parameters:**

| Name            | Type                           | Description                           |
| --------------- | ------------------------------ | ------------------------------------- |
| `origin`        | address                        | Origin of the transaction (tx.origin) |
| `sender`        | address                        | Sender of the call (msg.sender)       |
| `tradingParams` | struct LStrategy.TradingParams | New trading parameters                |

#### RatioParamsUpdated

```solidity
  event RatioParamsUpdated(address origin, address sender, struct LStrategy.RatioParams ratioParams)
```

Emitted when ratio params were updated

**Parameters:**

| Name          | Type                         | Description                           |
| ------------- | ---------------------------- | ------------------------------------- |
| `origin`      | address                      | Origin of the transaction (tx.origin) |
| `sender`      | address                      | Sender of the call (msg.sender)       |
| `ratioParams` | struct LStrategy.RatioParams | New ratio parameters                  |

#### OtherParamsUpdated

```solidity
  event OtherParamsUpdated(address origin, address sender, struct LStrategy.OtherParams otherParams)
```

Emitted when other params were updated

**Parameters:**

| Name          | Type                         | Description                           |
| ------------- | ---------------------------- | ------------------------------------- |
| `origin`      | address                      | Origin of the transaction (tx.origin) |
| `sender`      | address                      | Sender of the call (msg.sender)       |
| `otherParams` | struct LStrategy.OtherParams | New trading parameters                |

#### CowswapAllowanceReset

```solidity
  event CowswapAllowanceReset(address origin, address sender)
```

#### FeesCollected

```solidity
  event FeesCollected(address origin, address sender, uint256[] collectedEarnings)
```

## MStrategy

*Inherits from* [*DefaultAccessControlLateInit*](#defaultaccesscontrollateinit)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*Multicall*](#multicall)*,* [*ContractMeta*](#contractmeta)

⛽ 6.64M

### Functions

#### constructor

```solidity
  function constructor(contract INonfungiblePositionManager positionManager_, contract ISwapRouter router_) public
```

Deploys a new contract

**Parameters:**

| Name               | Type                                 | Description                 |
| ------------------ | ------------------------------------ | --------------------------- |
| `positionManager_` | contract INonfungiblePositionManager | Uniswap V3 position manager |
| `router_`          | contract ISwapRouter                 | Uniswap V3 swap router      |

**Specs**

* ✅ deploys a new contract

*Edge cases*

* ✅ when positionManager\_ address is zero reverts with AZ
* ✅ when router\_ address is zero passes

#### getAverageTick

```solidity
  function getAverageTick() external returns (int24 averageTick, int24 deviation)
```

UniV3 pool price stats

**Return Values:**

| Name          | Type  | Description                                                        |
| ------------- | ----- | ------------------------------------------------------------------ |
| `averageTick` | int24 | Average tick according to oracle and oracleParams.maxTickDeviation |
| `deviation`   | int24 | Current pool tick - average tick                                   |

**Specs**

* ✅ returns average UniswapV3Pool price tick

#### initialize

```solidity
  function initialize(contract INonfungiblePositionManager positionManager_, contract ISwapRouter router_, address[] tokens_, contract IERC20Vault erc20Vault_, contract IIntegrationVault moneyVault_, uint24 fee_, address admin_) external
```

Set initial values.

📕 Can be only called once.

**Parameters:**

| Name               | Type                                 | Description                                               |
| ------------------ | ------------------------------------ | --------------------------------------------------------- |
| `positionManager_` | contract INonfungiblePositionManager | Uniswap V3 position manager                               |
| `router_`          | contract ISwapRouter                 | Uniswap V3 swap router                                    |
| `tokens_`          | address\[]                           | Tokens under management                                   |
| `erc20Vault_`      | contract IERC20Vault                 | erc20Vault of the Strategy                                |
| `moneyVault_`      | contract IIntegrationVault           | moneyVault of the Strategy                                |
| `fee_`             | uint24                               | Uniswap V3 fee for the pool (needed for oracle and swaps) |
| `admin_`           | address                              | Admin of the strategy                                     |

#### createStrategy

⛽ 571K (570K - 573K)

```solidity
  function createStrategy(address[] tokens_, contract IERC20Vault erc20Vault_, contract IIntegrationVault moneyVault_, uint24 fee_, address admin_) external returns (contract MStrategy strategy)
```

Deploy a new strategy.

**Parameters:**

| Name          | Type                       | Description                                               |
| ------------- | -------------------------- | --------------------------------------------------------- |
| `tokens_`     | address\[]                 | Tokens under management                                   |
| `erc20Vault_` | contract IERC20Vault       | erc20Vault of the Strategy                                |
| `moneyVault_` | contract IIntegrationVault | moneyVault of the Strategy                                |
| `fee_`        | uint24                     | Uniswap V3 fee for the pool (needed for oracle and swaps) |
| `admin_`      | address                    | Admin of the new strategy                                 |

**Specs**

* ✅ creates a new strategy and initializes it

*Access control*

* ✅ allowed: any address

*Edge cases*

* ✅ when tokens.length is not equal 2 reverts with INVL
* ✅ when erc20Vault vaultTokens do not match tokens\_ reverts with INVA
* ✅ when moneyVault vaultTokens do not match tokens\_ reverts with INVA
* ✅ when UniSwapV3 pool for tokens does not exist reverts with AZ

#### rebalance

⛽ 725K (240K - 851K)

```solidity
  function rebalance(uint256[] minTokensAmount, bytes vaultOptions) external returns (int256[] poolAmounts, uint256[] tokenAmounts, bool zeroToOne)
```

Perform a rebalance according to target ratios

**Parameters:**

| Name              | Type       | Description                                                                         |
| ----------------- | ---------- | ----------------------------------------------------------------------------------- |
| `minTokensAmount` | uint256\[] | Lower bounds for amountOut of tokens, that we want to get after swap via SwapRouter |
| `vaultOptions`    | bytes      | Parameters of money vault for operations with it                                    |

**Return Values:**

| Name           | Type       | Description                                                                                                   |
| -------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| `poolAmounts`  | int256\[]  | The amount of each token that was pulled from erc20Vault to the money vault if positive, otherwise vice versa |
| `tokenAmounts` | uint256\[] | The amount of each token passed to and from SwapRouter dependings on zeroToOne                                |
| `zeroToOne`    | bool       | Flag, that true if we swapped amount of zero token to first token, otherwise false                            |

**Specs**

* ✅ performs a rebalance according to target ratios when token0/token1 ratio is greater than required
* ✅ performs a rebalance according to target ratios when token0/token1 ratio is less than required

*Access control*

* ✅ allowed: MStrategy admin
* ✅ allowed: MStrategy operator
* ✅ denied: any other address

*Edge cases*

* ✅ when absolute tick deviation >= oracle.maxTickDeviation reverts with INVA
* ✅ when tick is greater than tickMax - tickNeiborhood the upper bound of the interval is expanded by tickIncrease amount
* ✅ when tick is less than tickMin + tickNeiborhood the lower bound of the interval is expanded by tickIncrease amount
* ✅ when current tick has not deviated from the previous rebalance tick reverts with LIMU

#### manualPull

```solidity
  function manualPull(contract IIntegrationVault fromVault, contract IIntegrationVault toVault, uint256[] tokenAmounts, bytes vaultOptions) external
```

Manually pull tokens from fromVault to toVault

**Parameters:**

| Name           | Type                       | Description                 |
| -------------- | -------------------------- | --------------------------- |
| `fromVault`    | contract IIntegrationVault | Pull tokens from this vault |
| `toVault`      | contract IIntegrationVault | Pull tokens to this vault   |
| `tokenAmounts` | uint256\[]                 | Token amounts to pull       |

**Specs**

* ✅ pulls token amounts from fromVault to toVault

*Access control*

* ✅ allowed: MStrategy admin
* ✅ denied: any other address

*Edge cases*

* ✅ when token pull amounts are 0 passes

#### setOracleParams

⛽ 64K (41K - 75K)

```solidity
  function setOracleParams(struct MStrategy.OracleParams params) external
```

Set new Oracle params

**Parameters:**

| Name     | Type                          | Description   |
| -------- | ----------------------------- | ------------- |
| `params` | struct MStrategy.OracleParams | Params to set |

**Specs**

* ✅ sets new params for oracle
* ✅ edge cases: when maxSlippageD is more than DENOMINATOR reverts with INVA

*Access control*

* ✅ allowed: MStrategy admin
* ✅ denied: any other address

#### setRatioParams

⛽ 65K (44K - 124K)

```solidity
  function setRatioParams(struct MStrategy.RatioParams params) external
```

Set new Ratio params

**Parameters:**

| Name     | Type                         | Description   |
| -------- | ---------------------------- | ------------- |
| `params` | struct MStrategy.RatioParams | Params to set |

**Specs**

* ✅ sets new ratio params
* ✅ edge cases: tickMin is greater than tickMax reverts with INVA
* ✅ edge cases: when erc20MoneyRatioD is more than DENOMINATOR reverts with INVA
* ✅ edge cases: when minErc20MoneyRatioDeviationD is more than DENOMINATOR reverts with INVA

*Access control*

* ✅ allowed: MStrategy admin
* ✅ denied: any other address

### Structs

```solidity
struct OracleParams {
    uint32 oracleObservationDelta;
    uint24 maxTickDeviation;
    uint256 maxSlippageD;
}
```

```solidity
struct RatioParams {
    int24 tickMin;
    int24 tickMax;
    int24 minTickRebalanceThreshold;
    int24 tickNeighborhood;
    int24 tickIncrease;
    uint256 erc20MoneyRatioD;
    uint256 minErc20MoneyRatioDeviation0D;
    uint256 minErc20MoneyRatioDeviation1D;
}
```

```solidity
struct SwapToTargetParams {
    uint256 amountIn;
    address[] tokens;
    uint8 tokenInIndex;
    uint256 priceX96;
    uint256[] erc20Tvl;
    IUniswapV3Pool pool;
    ISwapRouter router;
    IIntegrationVault erc20Vault;
    IIntegrationVault moneyVault;
}
```

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### RebalancedPools

```solidity
  event RebalancedPools(int256[] tokenAmounts)
```

Emitted when pool rebalance is initiated.

**Parameters:**

| Name           | Type      | Description                                                                          |
| -------------- | --------- | ------------------------------------------------------------------------------------ |
| `tokenAmounts` | int256\[] | Token amounts for rebalance, negative means erc20Vault => moneyVault and vice versa. |

#### SwappedTokens

```solidity
  event SwappedTokens(struct MStrategy.SwapToTargetParams params)
```

Emitted when swap is initiated.

**Parameters:**

| Name     | Type                                | Description |
| -------- | ----------------------------------- | ----------- |
| `params` | struct MStrategy.SwapToTargetParams | Swap params |

#### SetOracleParams

```solidity
  event SetOracleParams(address origin, address sender, struct MStrategy.OracleParams params)
```

Emitted when Oracle params are set.

**Parameters:**

| Name     | Type                          | Description                           |
| -------- | ----------------------------- | ------------------------------------- |
| `origin` | address                       | Origin of the transaction (tx.origin) |
| `sender` | address                       | Sender of the call (msg.sender)       |
| `params` | struct MStrategy.OracleParams | Updated params                        |

#### SetRatioParams

```solidity
  event SetRatioParams(address origin, address sender, struct MStrategy.RatioParams params)
```

Emitted when Ratio params are set.

**Parameters:**

| Name     | Type                         | Description                           |
| -------- | ---------------------------- | ------------------------------------- |
| `origin` | address                      | Origin of the transaction (tx.origin) |
| `sender` | address                      | Sender of the call (msg.sender)       |
| `params` | struct MStrategy.RatioParams | Updated params                        |

## MultiPoolHStrategy

*Inherits from* [*DefaultAccessControlLateInit*](#defaultaccesscontrollateinit)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*Multicall*](#multicall)*,* [*ContractMeta*](#contractmeta)

⛽ 5.84M

### Functions

#### constructor

```solidity
  function constructor() public
```

constructs a strategy

#### initialize

```solidity
  function initialize(struct MultiPoolHStrategy.ImmutableParams immutableParams_, struct MultiPoolHStrategy.MutableParams mutableParams_, address admin) external
```

initializes the strategy

**Parameters:**

| Name               | Type                                      | Description                                                   |
| ------------------ | ----------------------------------------- | ------------------------------------------------------------- |
| `immutableParams_` | struct MultiPoolHStrategy.ImmutableParams | structure with all immutable params of the strategy           |
| `mutableParams_`   | struct MultiPoolHStrategy.MutableParams   | structure with all mutable params of strategy for initial set |
| `admin`            | address                                   | the addres of the admin of the strategy                       |

#### createStrategy

⛽ 1.2M (1.18M - 1.25M)

```solidity
  function createStrategy(struct MultiPoolHStrategy.ImmutableParams immutableParams_, struct MultiPoolHStrategy.MutableParams mutableParams_, address admin) external returns (contract MultiPoolHStrategy strategy)
```

creates the clone of the strategy

**Parameters:**

| Name               | Type                                      | Description                                                   |
| ------------------ | ----------------------------------------- | ------------------------------------------------------------- |
| `immutableParams_` | struct MultiPoolHStrategy.ImmutableParams | structure with all immutable params of the strategy           |
| `mutableParams_`   | struct MultiPoolHStrategy.MutableParams   | structure with all mutable params of strategy for initial set |
| `admin`            | address                                   | the addres of the admin of the strategy                       |

**Return Values:**

| Name       | Type                        | Description                               |
| ---------- | --------------------------- | ----------------------------------------- |
| `strategy` | contract MultiPoolHStrategy | new cloned strategy with for given params |

#### updateMutableParams

```solidity
  function updateMutableParams(struct MultiPoolHStrategy.MutableParams mutableParams_) external
```

updates parameters of the strategy. Can be called only by admin

**Parameters:**

| Name             | Type                                    | Description        |
| ---------------- | --------------------------------------- | ------------------ |
| `mutableParams_` | struct MultiPoolHStrategy.MutableParams | the new parameters |

#### rebalance

⛽ 3.41M

```solidity
  function rebalance(struct MultiPoolHStrategyRebalancer.Restrictions restrictions) external returns (struct MultiPoolHStrategyRebalancer.Restrictions actualAmounts)
```

rebalance method. Need to be called if the new position is needed

**Parameters:**

| Name           | Type                                             | Description                                                                           |
| -------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------- |
| `restrictions` | struct MultiPoolHStrategyRebalancer.Restrictions | the restrictions of the amount of tokens to be transferred and positions to be minted |

**Return Values:**

| Name            | Type                                             | Description                                           |
| --------------- | ------------------------------------------------ | ----------------------------------------------------- |
| `actualAmounts` | struct MultiPoolHStrategyRebalancer.Restrictions | actual transferred token amounts and minted positions |

**Specs**

* ✅ works correctly

#### checkMutableParams

```solidity
  function checkMutableParams(struct MultiPoolHStrategy.MutableParams mutableParams_) public
```

the function checks that mutableParams\_ pass the necessary checks

**Parameters:**

| Name             | Type                                    | Description          |
| ---------------- | --------------------------------------- | -------------------- |
| `mutableParams_` | struct MultiPoolHStrategy.MutableParams | params to be checked |

### Structs

```solidity
struct ImmutableParams {
    address[] tokens;
    IERC20Vault erc20Vault;
    IIntegrationVault moneyVault;
    address router;
    MultiPoolHStrategyRebalancer rebalancer;
    IUniV3Vault[] uniV3Vaults;
    int24 tickSpacing;
}
```

```solidity
struct MutableParams {
    int24 halfOfShortInterval;
    int24 domainLowerTick;
    int24 domainUpperTick;
    int24 maxTickDeviation;
    uint32 averageTickTimespan;
    uint256 amount0ForMint;
    uint256 amount1ForMint;
    uint256 erc20CapitalRatioD;
    uint256[] uniV3Weights;
    IUniswapV3Pool swapPool;
}
```

```solidity
struct Interval {
    int24 lowerTick;
    int24 upperTick;
}
```

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### UpdateMutableParams

```solidity
  event UpdateMutableParams(address origin, address sender, struct MultiPoolHStrategy.MutableParams mutableParams)
```

Emitted when Strategy mutableParams are set.

**Parameters:**

| Name            | Type                                    | Description                           |
| --------------- | --------------------------------------- | ------------------------------------- |
| `origin`        | address                                 | Origin of the transaction (tx.origin) |
| `sender`        | address                                 | Sender of the call (msg.sender)       |
| `mutableParams` | struct MultiPoolHStrategy.MutableParams | Updated mutableParams                 |

#### Rebalance

```solidity
  event Rebalance(address sender, address origin, struct MultiPoolHStrategyRebalancer.Restrictions expectedAmounts, struct MultiPoolHStrategyRebalancer.Restrictions actualAmounts)
```

Emitted when Strategy mutableParams are set.

**Parameters:**

| Name              | Type                                             | Description                                                   |
| ----------------- | ------------------------------------------------ | ------------------------------------------------------------- |
| `origin`          | address                                          | Origin of the transaction (tx.origin)                         |
| `sender`          | address                                          | Sender of the call (msg.sender)                               |
| `expectedAmounts` | struct MultiPoolHStrategyRebalancer.Restrictions | expected amounts to be transferred and positions to be minted |
| `actualAmounts`   | struct MultiPoolHStrategyRebalancer.Restrictions | actual transferred amounts and minted positions               |

## PulseRouteStrategy

*Inherits from* [*DefaultAccessControlLateInit*](#defaultaccesscontrollateinit)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*Multicall*](#multicall)*,* [*ContractMeta*](#contractmeta)

### Functions

#### constructor

```solidity
  function constructor(contract INonfungiblePositionManager positionManager_) public
```

**Parameters:**

| Name               | Type                                 | Description                           |
| ------------------ | ------------------------------------ | ------------------------------------- |
| `positionManager_` | contract INonfungiblePositionManager | Uniswap v3 NonfungiblePositionManager |

#### initialize

```solidity
  function initialize(struct PulseRouteStrategy.ImmutableParams immutableParams_, address admin) external
```

**Parameters:**

| Name               | Type                                      | Description                                         |
| ------------------ | ----------------------------------------- | --------------------------------------------------- |
| `immutableParams_` | struct PulseRouteStrategy.ImmutableParams | structure with all immutable params of the strategy |
| `admin`            | address                                   | admin of the strategy                               |

#### updateMutableParams

```solidity
  function updateMutableParams(struct PulseRouteStrategy.MutableParams mutableParams_) external
```

📕 updates mutable params of the strategy. Only the admin can call the function

**Parameters:**

| Name             | Type                                    | Description       |
| ---------------- | --------------------------------------- | ----------------- |
| `mutableParams_` | struct PulseRouteStrategy.MutableParams | new params to set |

#### rebalance

```solidity
  function rebalance(uint256 deadline) external
```

📕 Rebalancing goes like this:

1. Function checks the current states of the pools, and if the volatility is significant, the transaction reverts.
2. If necessary, a new position is minted on uniV3Vault, and the previous one is burned.
3. Tokens on erc20Vault are swapped via swapRouter so that the proportion matches the tokens on uniV3Vault.
4. The strategy transfers all possible tokens from erc20Vault to uniV3Vault. Only users with administrator or operator roles can call the function.

**Parameters:**

| Name       | Type    | Description                                          |
| ---------- | ------- | ---------------------------------------------------- |
| `deadline` | uint256 | Timestamp by which the transaction must be completed |

#### calculateNewInterval

```solidity
  function calculateNewInterval(struct PulseRouteStrategy.MutableParams mutableParams_, int24 tick, contract IUniswapV3Pool pool) public returns (int24 lowerTick, int24 upperTick)
```

📕 calculates a new interval according to the mutable params, the tickSpacing of the pool and the spot tick

**Parameters:**

| Name             | Type                                    | Description                                               |
| ---------------- | --------------------------------------- | --------------------------------------------------------- |
| `mutableParams_` | struct PulseRouteStrategy.MutableParams | structure with all mutable params of the strategy         |
| `tick`           | int24                                   | current spot tick of the pool                             |
| `pool`           | contract IUniswapV3Pool                 | the UniV3Vault pool where the new position will be minted |

**Return Values:**

| Name        | Type  | Description                    |
| ----------- | ----- | ------------------------------ |
| `lowerTick` | int24 | lower tick of the new interval |
| `upperTick` | int24 | upper tick of the new interval |

#### checkMutableParams

```solidity
  function checkMutableParams(struct PulseRouteStrategy.MutableParams params, struct PulseRouteStrategy.ImmutableParams immutableParams_) public
```

📕 checks mutable params according to strategy restrictions

**Parameters:**

| Name               | Type                                      | Description                                         |
| ------------------ | ----------------------------------------- | --------------------------------------------------- |
| `params`           | struct PulseRouteStrategy.MutableParams   | mutable parameters to be checked                    |
| `immutableParams_` | struct PulseRouteStrategy.ImmutableParams | structure with all immutable params of the strategy |

#### checkImmutableParams

```solidity
  function checkImmutableParams(struct PulseRouteStrategy.ImmutableParams params) public
```

📕 checks immutable params according to strategy restrictions

**Parameters:**

| Name     | Type                                      | Description                        |
| -------- | ----------------------------------------- | ---------------------------------- |
| `params` | struct PulseRouteStrategy.ImmutableParams | immutable parameters to be checked |

#### checkTickDeviations

```solidity
  function checkTickDeviations(struct PulseRouteStrategy.MutableParams mutableParams_, contract IUniswapV3Pool vaultPool, int24 spotTick) public
```

**Parameters:**

| Name             | Type                                    | Description                                       |
| ---------------- | --------------------------------------- | ------------------------------------------------- |
| `mutableParams_` | struct PulseRouteStrategy.MutableParams | structure with all mutable params of the strategy |
| `vaultPool`      | contract IUniswapV3Pool                 | UniswapV3Pool of uniV3Vault                       |
| `spotTick`       | int24                                   | current spot tick of UniswapV3Pool of uniV3Vault  |

#### calculateTargetRatioOfToken1

```solidity
  function calculateTargetRatioOfToken1(struct PulseRouteStrategy.Interval interval, uint160 sqrtSpotPriceX96, uint256 spotPriceX96) public returns (uint256 targetRatioOfToken1X96)
```

📕 calculate target ratio of token 1 to total capital after rebalance

**Parameters:**

| Name               | Type                               | Description                    |
| ------------------ | ---------------------------------- | ------------------------------ |
| `interval`         | struct PulseRouteStrategy.Interval | current interval on uniV3Vault |
| `sqrtSpotPriceX96` | uint160                            | sqrt price X96 of spot tick    |
| `spotPriceX96`     | uint256                            | price X96 of spot tick         |

**Return Values:**

| Name                     | Type    | Description                         |
| ------------------------ | ------- | ----------------------------------- |
| `targetRatioOfToken1X96` | uint256 | ratio of token 1 multiplied by 2^96 |

#### calculateAmountsForSwap

```solidity
  function calculateAmountsForSwap(struct PulseRouteStrategy.ImmutableParams immutableParams_, struct PulseRouteStrategy.MutableParams mutableParams_, uint256 priceX96, uint256 targetRatioOfToken1X96) public returns (uint256 tokenInIndex, uint256 amountIn)
```

📕 notion link: <https://www.notion.so/mellowprotocol/Swap-formula-53807cbf5c5641eda937dd1847d70f43> calculates the token that needs to be swapped and its amount to get the target ratio of tokens in the erc20Vault.

**Parameters:**

| Name                     | Type                                      | Description                                              |
| ------------------------ | ----------------------------------------- | -------------------------------------------------------- |
| `immutableParams_`       | struct PulseRouteStrategy.ImmutableParams | structure with all immutable params of the strategy      |
| `mutableParams_`         | struct PulseRouteStrategy.MutableParams   | structure with all mutable params of the strategy        |
| `priceX96`               | uint256                                   | price X96 of spot tick                                   |
| `targetRatioOfToken1X96` | uint256                                   | target ratio of token 1 to total capital after rebalance |

**Return Values:**

| Name           | Type    | Description              |
| -------------- | ------- | ------------------------ |
| `tokenInIndex` | uint256 | swap token index         |
| `amountIn`     | uint256 | number of tokens to swap |

#### depositCallback

```solidity
  function depositCallback() external
```

Function, that ERC20RootVault calling after deposit

#### withdrawCallback

```solidity
  function withdrawCallback() external
```

Function, that ERC20RootVault calling after withdraw

### Structs

```solidity
struct ImmutableParams {
    address router;
    IERC20Vault erc20Vault;
    IUniV3Vault uniV3Vault;
    address[] tokens;
}
```

```solidity
struct MutableParams {
    uint24 priceImpactD6;
    int24 intervalWidth;
    int24 tickNeighborhood;
    int24 maxDeviationForVaultPool;
    uint32 timespanForAverageTick;
    bytes pathZeroToOne;
    bytes pathOneToZero;
    uint256 amount0Desired;
    uint256 amount1Desired;
    uint256 swapSlippageD;
    uint256[] minSwapAmounts;
}
```

```solidity
struct Interval {
    int24 lowerTick;
    int24 upperTick;
}
```

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### TokensSwapped

```solidity
  event TokensSwapped(struct ISwapRouter.ExactInputParams swapParams, uint256 amountOut)
```

Emitted after a successful token swap

**Parameters:**

| Name         | Type                                | Description                                                          |
| ------------ | ----------------------------------- | -------------------------------------------------------------------- |
| `swapParams` | struct ISwapRouter.ExactInputParams | structure with different parameters for handling swap via swapRouter |
| `amountOut`  | uint256                             | the actual amount received from the swapRouter during swaps          |

#### UpdateMutableParams

```solidity
  event UpdateMutableParams(address origin, address sender, struct PulseRouteStrategy.MutableParams mutableParams)
```

Emited when mutable parameters are successfully updated

**Parameters:**

| Name            | Type                                    | Description                           |
| --------------- | --------------------------------------- | ------------------------------------- |
| `origin`        | address                                 | Origin of the transaction (tx.origin) |
| `sender`        | address                                 | Sender of the call (msg.sender)       |
| `mutableParams` | struct PulseRouteStrategy.MutableParams | Updated parameters                    |

#### Rebalance

```solidity
  event Rebalance(address origin, address sender)
```

Emited when the rebalance is successfully completed

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |

#### PositionMinted

```solidity
  event PositionMinted(uint256 tokenId)
```

Emited when a new uniswap position is created

**Parameters:**

| Name      | Type    | Description                 |
| --------- | ------- | --------------------------- |
| `tokenId` | uint256 | nft of new uniswap position |

#### PositionBurned

```solidity
  event PositionBurned(uint256 tokenId)
```

Emited when a uniswap position is burned

**Parameters:**

| Name      | Type    | Description             |
| --------- | ------- | ----------------------- |
| `tokenId` | uint256 | nft of uniswap position |

## PulseStrategy

*Inherits from* [*DefaultAccessControlLateInit*](#defaultaccesscontrollateinit)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*Multicall*](#multicall)*,* [*ContractMeta*](#contractmeta)

### Functions

#### constructor

```solidity
  function constructor(contract INonfungiblePositionManager positionManager_) public
```

**Parameters:**

| Name               | Type                                 | Description                           |
| ------------------ | ------------------------------------ | ------------------------------------- |
| `positionManager_` | contract INonfungiblePositionManager | Uniswap v3 NonfungiblePositionManager |

#### initialize

```solidity
  function initialize(struct PulseStrategy.ImmutableParams immutableParams_, address admin) external
```

**Parameters:**

| Name               | Type                                 | Description                                         |
| ------------------ | ------------------------------------ | --------------------------------------------------- |
| `immutableParams_` | struct PulseStrategy.ImmutableParams | structure with all immutable params of the strategy |
| `admin`            | address                              | admin of the strategy                               |

#### updateMutableParams

```solidity
  function updateMutableParams(struct PulseStrategy.MutableParams mutableParams_) external
```

📕 updates mutable params of the strategy. Only the admin can call the function

**Parameters:**

| Name             | Type                               | Description       |
| ---------------- | ---------------------------------- | ----------------- |
| `mutableParams_` | struct PulseStrategy.MutableParams | new params to set |

#### rebalance

```solidity
  function rebalance(uint256 deadline, bytes swapData) external
```

📕 Rebalancing goes like this:

1. Function checks the current states of the pools, and if the volatility is significant, the transaction reverts.
2. If necessary, a new position is minted on uniV3Vault, and the previous one is burned.
3. Tokens on erc20Vault are swapped via AggregationRouterV5 so that the proportion matches the tokens on uniV3Vault.
4. The strategy transfers all possible tokens from erc20Vault to uniV3Vault. Only users with administrator or operator roles can call the function.

**Parameters:**

| Name       | Type    | Description                                          |
| ---------- | ------- | ---------------------------------------------------- |
| `deadline` | uint256 | Timestamp by which the transaction must be completed |
| `swapData` | bytes   | Data for swap on 1inch AggregationRouterV5           |

#### checkMutableParams

```solidity
  function checkMutableParams(struct PulseStrategy.MutableParams params, struct PulseStrategy.ImmutableParams immutableParams_) public
```

📕 checks mutable params according to strategy restrictions

**Parameters:**

| Name               | Type                                 | Description                                         |
| ------------------ | ------------------------------------ | --------------------------------------------------- |
| `params`           | struct PulseStrategy.MutableParams   | mutable parameters to be checked                    |
| `immutableParams_` | struct PulseStrategy.ImmutableParams | structure with all immutable params of the strategy |

#### checkImmutableParams

```solidity
  function checkImmutableParams(struct PulseStrategy.ImmutableParams params) public
```

📕 checks immutable params according to strategy restrictions

**Parameters:**

| Name     | Type                                 | Description                        |
| -------- | ------------------------------------ | ---------------------------------- |
| `params` | struct PulseStrategy.ImmutableParams | immutable parameters to be checked |

#### checkTickDeviation

```solidity
  function checkTickDeviation(struct PulseStrategy.MutableParams mutableParams_, contract IUniswapV3Pool vaultPool) public
```

📕 checks deviation of spot ticks of all pools in strategy from corresponding average ticks. If any deviation is large than maxDevation parameter for the pool, then the transaction will be reverted with a LIMIT\_OVERFLOW error. If there are no observations 10 seconds ago in any of the considered pools, then the transaction will be reverted with an INVALID\_STATE error.

**Parameters:**

| Name             | Type                               | Description                                       |
| ---------------- | ---------------------------------- | ------------------------------------------------- |
| `mutableParams_` | struct PulseStrategy.MutableParams | structure with all mutable params of the strategy |
| `vaultPool`      | contract IUniswapV3Pool            | UniswapV3Pool of uniV3Vault                       |

#### calculateNewPosition

```solidity
  function calculateNewPosition(struct PulseStrategy.MutableParams mutableParams_, int24 spotTick, contract IUniswapV3Pool pool, uint256 uniV3Nft) public returns (struct PulseStrategy.Interval newInterval, bool neededNewInterval)
```

**Parameters:**

| Name             | Type                               | Description                                       |
| ---------------- | ---------------------------------- | ------------------------------------------------- |
| `mutableParams_` | struct PulseStrategy.MutableParams | structure with all mutable params of the strategy |
| `spotTick`       | int24                              | current spot tick of UniswapV3Pool of uniV3Vault  |
| `pool`           | contract IUniswapV3Pool            | UniswapV3Pool of uniV3Vault                       |
| `uniV3Nft`       | uint256                            | Nft of uniswap position                           |

**Return Values:**

| Name                | Type                          | Description                                            |
| ------------------- | ----------------------------- | ------------------------------------------------------ |
| `newInterval`       | struct PulseStrategy.Interval | expected interval after reblance                       |
| `neededNewInterval` | bool                          | flag that is true if it is needed to mint new interval |

#### calculateTargetRatioOfToken1

```solidity
  function calculateTargetRatioOfToken1(struct PulseStrategy.Interval interval, uint160 sqrtSpotPriceX96, uint256 spotPriceX96) public returns (uint256 targetRatioOfToken1X96)
```

📕 calculate target ratio of token 1 to total capital after rebalance

**Parameters:**

| Name               | Type                          | Description                    |
| ------------------ | ----------------------------- | ------------------------------ |
| `interval`         | struct PulseStrategy.Interval | current interval on uniV3Vault |
| `sqrtSpotPriceX96` | uint160                       | sqrt price X96 of spot tick    |
| `spotPriceX96`     | uint256                       | price X96 of spot tick         |

**Return Values:**

| Name                     | Type    | Description                         |
| ------------------------ | ------- | ----------------------------------- |
| `targetRatioOfToken1X96` | uint256 | ratio of token 1 multiplied by 2^96 |

#### calculateAmountsForSwap

```solidity
  function calculateAmountsForSwap(struct PulseStrategy.ImmutableParams immutableParams_, struct PulseStrategy.MutableParams mutableParams_, uint256 priceX96, uint256 targetRatioOfToken1X96) public returns (uint256 tokenInIndex, uint256 amountIn)
```

📕 notion link: <https://www.notion.so/mellowprotocol/Swap-formula-53807cbf5c5641eda937dd1847d70f43> calculates the token that needs to be swapped and its amount to get the target ratio of tokens in the erc20Vault.

**Parameters:**

| Name                     | Type                                 | Description                                              |
| ------------------------ | ------------------------------------ | -------------------------------------------------------- |
| `immutableParams_`       | struct PulseStrategy.ImmutableParams | structure with all immutable params of the strategy      |
| `mutableParams_`         | struct PulseStrategy.MutableParams   | structure with all mutable params of the strategy        |
| `priceX96`               | uint256                              | price X96 of spot tick                                   |
| `targetRatioOfToken1X96` | uint256                              | target ratio of token 1 to total capital after rebalance |

**Return Values:**

| Name           | Type    | Description              |
| -------------- | ------- | ------------------------ |
| `tokenInIndex` | uint256 | swap token index         |
| `amountIn`     | uint256 | number of tokens to swap |

#### depositCallback

```solidity
  function depositCallback() external
```

Function, that ERC20RootVault calling after deposit

#### withdrawCallback

```solidity
  function withdrawCallback() external
```

Function, that ERC20RootVault calling after withdraw

### Structs

```solidity
struct ImmutableParams {
    address router;
    IERC20Vault erc20Vault;
    IUniV3Vault uniV3Vault;
    address[] tokens;
}
```

```solidity
struct MutableParams {
    int24 priceImpactD6;
    int24 intervalWidth;
    int24 tickNeighborhood;
    int24 maxDeviationForVaultPool;
    uint32 timespanForAverageTick;
    uint256 amount0Desired;
    uint256 amount1Desired;
    uint256 swapSlippageD;
    uint256 swappingAmountsCoefficientD;
    uint256[] minSwapAmounts;
}
```

```solidity
struct Interval {
    int24 lowerTick;
    int24 upperTick;
}
```

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### TokensSwapped

```solidity
  event TokensSwapped(uint256 amountIn, uint256 amountOut, uint256 tokenInIndex)
```

Emitted after a successful token swap

**Parameters:**

| Name           | Type    | Description                                    |
| -------------- | ------- | ---------------------------------------------- |
| `amountIn`     | uint256 | amount of token, that pushed into SwapRouter   |
| `amountOut`    | uint256 | amount of token, that recieved from SwapRouter |
| `tokenInIndex` | uint256 | index of token, that pushed into SwapRouter    |

#### UpdateMutableParams

```solidity
  event UpdateMutableParams(address origin, address sender, struct PulseStrategy.MutableParams mutableParams)
```

Emited when mutable parameters are successfully updated

**Parameters:**

| Name            | Type                               | Description                           |
| --------------- | ---------------------------------- | ------------------------------------- |
| `origin`        | address                            | Origin of the transaction (tx.origin) |
| `sender`        | address                            | Sender of the call (msg.sender)       |
| `mutableParams` | struct PulseStrategy.MutableParams | Updated parameters                    |

#### Rebalance

```solidity
  event Rebalance(address origin, address sender)
```

Emited when the rebalance is successfully completed

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |

#### PositionMinted

```solidity
  event PositionMinted(uint256 tokenId)
```

Emited when a new uniswap position is created

**Parameters:**

| Name      | Type    | Description                 |
| --------- | ------- | --------------------------- |
| `tokenId` | uint256 | nft of new uniswap position |

#### PositionBurned

```solidity
  event PositionBurned(uint256 tokenId)
```

Emited when a uniswap position is burned

**Parameters:**

| Name      | Type    | Description             |
| --------- | ------- | ----------------------- |
| `tokenId` | uint256 | nft of uniswap position |

## PulseStrategyV2

*Inherits from* [*DefaultAccessControlLateInit*](#defaultaccesscontrollateinit)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*Multicall*](#multicall)*,* [*ContractMeta*](#contractmeta)

### Functions

#### constructor

```solidity
  function constructor(contract INonfungiblePositionManager positionManager_) public
```

**Parameters:**

| Name               | Type                                 | Description                           |
| ------------------ | ------------------------------------ | ------------------------------------- |
| `positionManager_` | contract INonfungiblePositionManager | Uniswap v3 NonfungiblePositionManager |

#### initialize

```solidity
  function initialize(struct PulseStrategyV2.ImmutableParams immutableParams_, address admin) external
```

**Parameters:**

| Name               | Type                                   | Description                                         |
| ------------------ | -------------------------------------- | --------------------------------------------------- |
| `immutableParams_` | struct PulseStrategyV2.ImmutableParams | structure with all immutable params of the strategy |
| `admin`            | address                                | admin of the strategy                               |

#### setForceRebalanceFlag

```solidity
  function setForceRebalanceFlag(bool newValue) external
```

#### updateDesiredAmounts

```solidity
  function updateDesiredAmounts(struct PulseStrategyV2.DesiredAmounts params) external
```

#### updateMutableParams

```solidity
  function updateMutableParams(struct PulseStrategyV2.MutableParams mutableParams_) external
```

📕 updates mutable params of the strategy. Only the admin can call the function

**Parameters:**

| Name             | Type                                 | Description       |
| ---------------- | ------------------------------------ | ----------------- |
| `mutableParams_` | struct PulseStrategyV2.MutableParams | new params to set |

#### rebalance

```solidity
  function rebalance(uint256 deadline, bytes swapData, uint256 minAmountOutInCaseOfSwap) external
```

📕 Rebalancing goes like this:

1. Function checks the current states of the pools, and if the volatility is significant, the transaction reverts.
2. If necessary, a new position is minted on uniV3Vault, and the previous one is burned.
3. Tokens on erc20Vault are swapped via AggregationRouterV5 so that the proportion matches the tokens on uniV3Vault.
4. The strategy transfers all possible tokens from erc20Vault to uniV3Vault. Only users with administrator or operator roles can call the function.

**Parameters:**

| Name       | Type    | Description                                          |
| ---------- | ------- | ---------------------------------------------------- |
| `deadline` | uint256 | Timestamp by which the transaction must be completed |
| `swapData` | bytes   | Data for swap on 1inch AggregationRouterV5           |

#### checkMutableParams

```solidity
  function checkMutableParams(struct PulseStrategyV2.MutableParams params, struct PulseStrategyV2.ImmutableParams immutableParams_) public
```

📕 checks mutable params according to strategy restrictions

**Parameters:**

| Name               | Type                                   | Description                                         |
| ------------------ | -------------------------------------- | --------------------------------------------------- |
| `params`           | struct PulseStrategyV2.MutableParams   | mutable parameters to be checked                    |
| `immutableParams_` | struct PulseStrategyV2.ImmutableParams | structure with all immutable params of the strategy |

#### checkImmutableParams

```solidity
  function checkImmutableParams(struct PulseStrategyV2.ImmutableParams params) public
```

📕 checks immutable params according to strategy restrictions

**Parameters:**

| Name     | Type                                   | Description                        |
| -------- | -------------------------------------- | ---------------------------------- |
| `params` | struct PulseStrategyV2.ImmutableParams | immutable parameters to be checked |

#### checkTickDeviation

```solidity
  function checkTickDeviation(struct PulseStrategyV2.MutableParams mutableParams_, contract IUniswapV3Pool vaultPool) public
```

📕 checks deviation of spot ticks of all pools in strategy from corresponding average ticks. If any deviation is large than maxDevation parameter for the pool, then the transaction will be reverted with a LIMIT\_OVERFLOW error. If there are no observations 10 seconds ago in any of the considered pools, then the transaction will be reverted with an INVALID\_STATE error.

**Parameters:**

| Name             | Type                                 | Description                                       |
| ---------------- | ------------------------------------ | ------------------------------------------------- |
| `mutableParams_` | struct PulseStrategyV2.MutableParams | structure with all mutable params of the strategy |
| `vaultPool`      | contract IUniswapV3Pool              | UniswapV3Pool of uniV3Vault                       |

#### formPositionWithSpotTickInCenter

```solidity
  function formPositionWithSpotTickInCenter(struct PulseStrategyV2.MutableParams mutableParams_, int24 spotTick, int24 tickSpacing) public returns (struct PulseStrategyV2.Interval newInterval)
```

#### calculateNewPosition

```solidity
  function calculateNewPosition(struct PulseStrategyV2.MutableParams mutableParams_, int24 spotTick, contract IUniswapV3Pool pool, uint256 uniV3Nft) public returns (struct PulseStrategyV2.Interval newInterval, bool neededNewInterval)
```

**Parameters:**

| Name             | Type                                 | Description                                       |
| ---------------- | ------------------------------------ | ------------------------------------------------- |
| `mutableParams_` | struct PulseStrategyV2.MutableParams | structure with all mutable params of the strategy |
| `spotTick`       | int24                                | current spot tick of UniswapV3Pool of uniV3Vault  |
| `pool`           | contract IUniswapV3Pool              | UniswapV3Pool of uniV3Vault                       |
| `uniV3Nft`       | uint256                              | Nft of uniswap position                           |

**Return Values:**

| Name                | Type                            | Description                                            |
| ------------------- | ------------------------------- | ------------------------------------------------------ |
| `newInterval`       | struct PulseStrategyV2.Interval | expected interval after reblance                       |
| `neededNewInterval` | bool                            | flag that is true if it is needed to mint new interval |

#### calculateTargetRatioOfToken1

```solidity
  function calculateTargetRatioOfToken1(struct PulseStrategyV2.Interval interval, uint160 sqrtSpotPriceX96, uint256 spotPriceX96) public returns (uint256 targetRatioOfToken1X96)
```

📕 calculate target ratio of token 1 to total capital after rebalance

**Parameters:**

| Name               | Type                            | Description                    |
| ------------------ | ------------------------------- | ------------------------------ |
| `interval`         | struct PulseStrategyV2.Interval | current interval on uniV3Vault |
| `sqrtSpotPriceX96` | uint160                         | sqrt price X96 of spot tick    |
| `spotPriceX96`     | uint256                         | price X96 of spot tick         |

**Return Values:**

| Name                     | Type    | Description                         |
| ------------------------ | ------- | ----------------------------------- |
| `targetRatioOfToken1X96` | uint256 | ratio of token 1 multiplied by 2^96 |

#### calculateAmountsForSwap

```solidity
  function calculateAmountsForSwap(struct PulseStrategyV2.ImmutableParams immutableParams_, struct PulseStrategyV2.MutableParams mutableParams_, uint256 priceX96, uint256 targetRatioOfToken1X96) public returns (uint256 tokenInIndex, uint256 amountIn)
```

📕 notion link: <https://www.notion.so/mellowprotocol/Swap-formula-53807cbf5c5641eda937dd1847d70f43> calculates the token that needs to be swapped and its amount to get the target ratio of tokens in the erc20Vault.

**Parameters:**

| Name                     | Type                                   | Description                                              |
| ------------------------ | -------------------------------------- | -------------------------------------------------------- |
| `immutableParams_`       | struct PulseStrategyV2.ImmutableParams | structure with all immutable params of the strategy      |
| `mutableParams_`         | struct PulseStrategyV2.MutableParams   | structure with all mutable params of the strategy        |
| `priceX96`               | uint256                                | price X96 of spot tick                                   |
| `targetRatioOfToken1X96` | uint256                                | target ratio of token 1 to total capital after rebalance |

**Return Values:**

| Name           | Type    | Description              |
| -------------- | ------- | ------------------------ |
| `tokenInIndex` | uint256 | swap token index         |
| `amountIn`     | uint256 | number of tokens to swap |

#### depositCallback

```solidity
  function depositCallback() external
```

Function, that ERC20RootVault calling after deposit

#### withdrawCallback

```solidity
  function withdrawCallback() external
```

Function, that ERC20RootVault calling after withdraw

### Structs

```solidity
struct ImmutableParams {
    IERC20Vault erc20Vault;
    IUniV3Vault uniV3Vault;
    address router;
    address[] tokens;
}
```

```solidity
struct MutableParams {
    int24 priceImpactD6;
    int24 defaultIntervalWidth;
    int24 maxPositionLengthInTicks;
    int24 maxDeviationForVaultPool;
    uint32 timespanForAverageTick;
    uint256 neighborhoodFactorD;
    uint256 extensionFactorD;
    uint256 swapSlippageD;
    uint256 swappingAmountsCoefficientD;
    uint256[] minSwapAmounts;
}
```

```solidity
struct DesiredAmounts {
    uint256 amount0Desired;
    uint256 amount1Desired;
}
```

```solidity
struct Interval {
    int24 lowerTick;
    int24 upperTick;
}
```

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### TokensSwapped

```solidity
  event TokensSwapped(uint256 amountIn, uint256 amountOut, uint256 tokenInIndex)
```

Emitted after a successful token swap

**Parameters:**

| Name           | Type    | Description                                    |
| -------------- | ------- | ---------------------------------------------- |
| `amountIn`     | uint256 | amount of token, that pushed into SwapRouter   |
| `amountOut`    | uint256 | amount of token, that recieved from SwapRouter |
| `tokenInIndex` | uint256 | index of token, that pushed into SwapRouter    |

#### UpdateMutableParams

```solidity
  event UpdateMutableParams(address origin, address sender, struct PulseStrategyV2.MutableParams mutableParams)
```

Emited when mutable parameters are successfully updated

**Parameters:**

| Name            | Type                                 | Description                           |
| --------------- | ------------------------------------ | ------------------------------------- |
| `origin`        | address                              | Origin of the transaction (tx.origin) |
| `sender`        | address                              | Sender of the call (msg.sender)       |
| `mutableParams` | struct PulseStrategyV2.MutableParams | Updated parameters                    |

#### Rebalance

```solidity
  event Rebalance(address origin, address sender)
```

Emited when the rebalance is successfully completed

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |

#### PositionMinted

```solidity
  event PositionMinted(uint256 tokenId)
```

Emited when a new uniswap position is created

**Parameters:**

| Name      | Type    | Description                 |
| --------- | ------- | --------------------------- |
| `tokenId` | uint256 | nft of new uniswap position |

#### PositionBurned

```solidity
  event PositionBurned(uint256 tokenId)
```

Emited when a uniswap position is burned

**Parameters:**

| Name      | Type    | Description             |
| --------- | ------- | ----------------------- |
| `tokenId` | uint256 | nft of uniswap position |

## QuickPulseStrategy

*Inherits from* [*DefaultAccessControlLateInit*](#defaultaccesscontrollateinit)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*Multicall*](#multicall)*,* [*ContractMeta*](#contractmeta)

### Functions

#### constructor

```solidity
  function constructor(contract IAlgebraNonfungiblePositionManager positionManager_) public
```

**Parameters:**

| Name               | Type                                        | Description                        |
| ------------------ | ------------------------------------------- | ---------------------------------- |
| `positionManager_` | contract IAlgebraNonfungiblePositionManager | Algebra NonfungiblePositionManager |

#### initialize

```solidity
  function initialize(struct QuickPulseStrategy.ImmutableParams immutableParams_, address admin) external
```

**Parameters:**

| Name               | Type                                      | Description                                         |
| ------------------ | ----------------------------------------- | --------------------------------------------------- |
| `immutableParams_` | struct QuickPulseStrategy.ImmutableParams | structure with all immutable params of the strategy |
| `admin`            | address                                   | admin of the strategy                               |

#### updateMutableParams

```solidity
  function updateMutableParams(struct QuickPulseStrategy.MutableParams mutableParams_) external
```

📕 updates mutable params of the strategy. Only the admin can call the function

**Parameters:**

| Name             | Type                                    | Description       |
| ---------------- | --------------------------------------- | ----------------- |
| `mutableParams_` | struct QuickPulseStrategy.MutableParams | new params to set |

#### rebalance

```solidity
  function rebalance(uint256 deadline, bytes swapData) external
```

📕 Rebalancing goes like this:

1. Function checks the current states of the pools, and if the volatility is significant, the transaction reverts.
2. If necessary, a new position is minted on quickSwapVault, and the previous one is burned.
3. Tokens on erc20Vault are swapped via AggregationRouterV5 so that the proportion matches the tokens on quickSwapVault.
4. The strategy transfers all possible tokens from erc20Vault to quickSwapVault. Only users with administrator or operator roles can call the function.

**Parameters:**

| Name       | Type    | Description                                          |
| ---------- | ------- | ---------------------------------------------------- |
| `deadline` | uint256 | Timestamp by which the transaction must be completed |
| `swapData` | bytes   | Data for swap on 1inch AggregationRouterV5           |

#### checkMutableParams

```solidity
  function checkMutableParams(struct QuickPulseStrategy.MutableParams params) public
```

📕 checks mutable params according to strategy restrictions

**Parameters:**

| Name     | Type                                    | Description                      |
| -------- | --------------------------------------- | -------------------------------- |
| `params` | struct QuickPulseStrategy.MutableParams | mutable parameters to be checked |

#### checkImmutableParams

```solidity
  function checkImmutableParams(struct QuickPulseStrategy.ImmutableParams params) public
```

📕 checks immutable params according to strategy restrictions

**Parameters:**

| Name     | Type                                      | Description                        |
| -------- | ----------------------------------------- | ---------------------------------- |
| `params` | struct QuickPulseStrategy.ImmutableParams | immutable parameters to be checked |

#### checkTickDeviation

```solidity
  function checkTickDeviation(struct QuickPulseStrategy.MutableParams mutableParams_, contract IAlgebraPool vaultPool) public
```

📕 checks deviation of spot ticks of all pools in strategy from corresponding average ticks. If any deviation is large than maxDevation parameter for the pool, then the transaction will be reverted with a LIMIT\_OVERFLOW error. If there are no observations 10 seconds ago in any of the considered pools, then the transaction will be reverted with an INVALID\_STATE error.

**Parameters:**

| Name             | Type                                    | Description                                       |
| ---------------- | --------------------------------------- | ------------------------------------------------- |
| `mutableParams_` | struct QuickPulseStrategy.MutableParams | structure with all mutable params of the strategy |
| `vaultPool`      | contract IAlgebraPool                   | pool of quickSwapVault                            |

#### calculateNewPosition

```solidity
  function calculateNewPosition(struct QuickPulseStrategy.MutableParams mutableParams_, int24 spotTick, contract IAlgebraPool pool, uint256 positionNft) public returns (struct QuickPulseStrategy.Interval newInterval, bool neededNewInterval)
```

**Parameters:**

| Name             | Type                                    | Description                                        |
| ---------------- | --------------------------------------- | -------------------------------------------------- |
| `mutableParams_` | struct QuickPulseStrategy.MutableParams | structure with all mutable params of the strategy  |
| `spotTick`       | int24                                   | current spot tick of AlgebraPool of quickSwapVault |
| `pool`           | contract IAlgebraPool                   | AlgebraPool of quickSwapVault                      |
| `positionNft`    | uint256                                 | Nft of algebra position                            |

**Return Values:**

| Name                | Type                               | Description                                            |
| ------------------- | ---------------------------------- | ------------------------------------------------------ |
| `newInterval`       | struct QuickPulseStrategy.Interval | expected interval after reblance                       |
| `neededNewInterval` | bool                               | flag that is true if it is needed to mint new interval |

#### calculateTargetRatioOfToken1

```solidity
  function calculateTargetRatioOfToken1(struct QuickPulseStrategy.Interval interval, uint160 sqrtSpotPriceX96, uint256 spotPriceX96) public returns (uint256 targetRatioOfToken1X96)
```

📕 calculate target ratio of token 1 to total capital after rebalance

**Parameters:**

| Name               | Type                               | Description                        |
| ------------------ | ---------------------------------- | ---------------------------------- |
| `interval`         | struct QuickPulseStrategy.Interval | current interval on quickSwapVault |
| `sqrtSpotPriceX96` | uint160                            | sqrt price X96 of spot tick        |
| `spotPriceX96`     | uint256                            | price X96 of spot tick             |

**Return Values:**

| Name                     | Type    | Description                         |
| ------------------------ | ------- | ----------------------------------- |
| `targetRatioOfToken1X96` | uint256 | ratio of token 1 multiplied by 2^96 |

#### calculateAmountsForSwap

```solidity
  function calculateAmountsForSwap(struct QuickPulseStrategy.ImmutableParams immutableParams_, struct QuickPulseStrategy.MutableParams mutableParams_, uint256 priceX96, uint256 targetRatioOfToken1X96) public returns (uint256 tokenInIndex, uint256 amountIn)
```

📕 notion link: <https://www.notion.so/mellowprotocol/Swap-formula-53807cbf5c5641eda937dd1847d70f43> calculates the token that needs to be swapped and its amount to get the target ratio of tokens in the erc20Vault.

**Parameters:**

| Name                     | Type                                      | Description                                              |
| ------------------------ | ----------------------------------------- | -------------------------------------------------------- |
| `immutableParams_`       | struct QuickPulseStrategy.ImmutableParams | structure with all immutable params of the strategy      |
| `mutableParams_`         | struct QuickPulseStrategy.MutableParams   | structure with all mutable params of the strategy        |
| `priceX96`               | uint256                                   | price X96 of spot tick                                   |
| `targetRatioOfToken1X96` | uint256                                   | target ratio of token 1 to total capital after rebalance |

**Return Values:**

| Name           | Type    | Description              |
| -------------- | ------- | ------------------------ |
| `tokenInIndex` | uint256 | swap token index         |
| `amountIn`     | uint256 | number of tokens to swap |

#### depositCallback

```solidity
  function depositCallback() external
```

Function, that ERC20RootVault calling after deposit

#### withdrawCallback

```solidity
  function withdrawCallback() external
```

Function, that ERC20RootVault calling after withdraw

#### onERC721Received

⛽ 105K

```solidity
  function onERC721Received(address, address, uint256, bytes) external returns (bytes4)
```

📕 Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.

### Structs

```solidity
struct ImmutableParams {
    address router;
    IERC20Vault erc20Vault;
    IQuickSwapVault quickSwapVault;
    address[] tokens;
}
```

```solidity
struct MutableParams {
    int24 priceImpactD6;
    int24 intervalWidth;
    int24 tickNeighborhood;
    int24 maxDeviationForVaultPool;
    uint32 timespanForAverageTick;
    uint256 amount0Desired;
    uint256 amount1Desired;
    uint256 swapSlippageD;
    uint256 swappingAmountsCoefficientD;
    uint256[] minSwapAmounts;
}
```

```solidity
struct Interval {
    int24 lowerTick;
    int24 upperTick;
}
```

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### TokensSwapped

```solidity
  event TokensSwapped(uint256 amountIn, uint256 amountOut, uint256 tokenInIndex)
```

Emitted after a successful token swap

**Parameters:**

| Name           | Type    | Description                                    |
| -------------- | ------- | ---------------------------------------------- |
| `amountIn`     | uint256 | amount of token, that pushed into SwapRouter   |
| `amountOut`    | uint256 | amount of token, that recieved from SwapRouter |
| `tokenInIndex` | uint256 | index of token, that pushed into SwapRouter    |

#### UpdateMutableParams

```solidity
  event UpdateMutableParams(address origin, address sender, struct QuickPulseStrategy.MutableParams mutableParams)
```

Emited when mutable parameters are successfully updated

**Parameters:**

| Name            | Type                                    | Description                           |
| --------------- | --------------------------------------- | ------------------------------------- |
| `origin`        | address                                 | Origin of the transaction (tx.origin) |
| `sender`        | address                                 | Sender of the call (msg.sender)       |
| `mutableParams` | struct QuickPulseStrategy.MutableParams | Updated parameters                    |

#### Rebalance

```solidity
  event Rebalance(address origin, address sender)
```

Emited when the rebalance is successfully completed

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |

#### PositionMinted

```solidity
  event PositionMinted(uint256 tokenId)
```

Emited when a new algebra position is created

**Parameters:**

| Name      | Type    | Description                 |
| --------- | ------- | --------------------------- |
| `tokenId` | uint256 | nft of new algebra position |

#### PositionBurned

```solidity
  event PositionBurned(uint256 tokenId)
```

Emited when a algebra position is burned

**Parameters:**

| Name      | Type    | Description             |
| --------- | ------- | ----------------------- |
| `tokenId` | uint256 | nft of algebra position |

## SinglePositionQuickSwapStrategy

*Inherits from* [*DefaultAccessControlLateInit*](#defaultaccesscontrollateinit)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*Multicall*](#multicall)*,* [*ContractMeta*](#contractmeta)

### Functions

#### constructor

```solidity
  function constructor(contract IUniswapV3Factory uniswapV3Factory_, contract IAlgebraNonfungiblePositionManager algebraPositionManager_, contract SinglePositionStrategyHelper helper_) public
```

**Parameters:**

| Name                      | Type                                        | Description                        |
| ------------------------- | ------------------------------------------- | ---------------------------------- |
| `uniswapV3Factory_`       | contract IUniswapV3Factory                  | Uniswap V3 pool factory            |
| `algebraPositionManager_` | contract IAlgebraNonfungiblePositionManager | Algebra NonfungiblePositionManager |
| `helper_`                 | contract SinglePositionStrategyHelper       | strategy helper                    |

#### initialize

```solidity
  function initialize(struct SinglePositionQuickSwapStrategy.ImmutableParams immutableParams_, address admin) external
```

**Parameters:**

| Name               | Type                                                   | Description                                         |
| ------------------ | ------------------------------------------------------ | --------------------------------------------------- |
| `immutableParams_` | struct SinglePositionQuickSwapStrategy.ImmutableParams | structure with all immutable params of the strategy |
| `admin`            | address                                                | admin of the strategy                               |

#### updateMutableParams

```solidity
  function updateMutableParams(struct SinglePositionQuickSwapStrategy.MutableParams mutableParams_) external
```

📕 updates mutable params of the strategy. Only the admin can call the function

**Parameters:**

| Name             | Type                                                 | Description       |
| ---------------- | ---------------------------------------------------- | ----------------- |
| `mutableParams_` | struct SinglePositionQuickSwapStrategy.MutableParams | new params to set |

#### rebalance

```solidity
  function rebalance(uint256 deadline) external
```

📕 Rebalancing goes like this:

1. Function checks the current states of the pools, and if the volatility is significant, the transaction reverts.
2. If necessary, a new position is minted on quickSwapVault, and the previous one is burned.
3. Tokens on erc20Vault are swapped via swapRouter so that the proportion matches the tokens on quickSwapVault.
4. The strategy transfers all possible tokens from erc20Vault to quickSwapVault. Only users with administrator or operator roles can call the function.

**Parameters:**

| Name       | Type    | Description                                          |
| ---------- | ------- | ---------------------------------------------------- |
| `deadline` | uint256 | Timestamp by which the transaction must be completed |

#### calculateNewInterval

```solidity
  function calculateNewInterval(struct SinglePositionQuickSwapStrategy.MutableParams mutableParams_, int24 tick, contract IAlgebraPool pool) public returns (int24 lowerTick, int24 upperTick)
```

📕 calculates a new interval according to the mutable params, the tickSpacing of the pool and the spot tick

**Parameters:**

| Name             | Type                                                 | Description                                                   |
| ---------------- | ---------------------------------------------------- | ------------------------------------------------------------- |
| `mutableParams_` | struct SinglePositionQuickSwapStrategy.MutableParams | structure with all mutable params of the strategy             |
| `tick`           | int24                                                | current spot tick of the pool                                 |
| `pool`           | contract IAlgebraPool                                | the quickSwapVault pool where the new position will be minted |

**Return Values:**

| Name        | Type  | Description                    |
| ----------- | ----- | ------------------------------ |
| `lowerTick` | int24 | lower tick of the new interval |
| `upperTick` | int24 | upper tick of the new interval |

#### checkMutableParams

```solidity
  function checkMutableParams(struct SinglePositionQuickSwapStrategy.MutableParams params) public
```

📕 checks mutable params according to strategy restrictions

**Parameters:**

| Name     | Type                                                 | Description                      |
| -------- | ---------------------------------------------------- | -------------------------------- |
| `params` | struct SinglePositionQuickSwapStrategy.MutableParams | mutable parameters to be checked |

#### checkImmutableParams

```solidity
  function checkImmutableParams(struct SinglePositionQuickSwapStrategy.ImmutableParams params) public
```

📕 checks immutable params according to strategy restrictions

**Parameters:**

| Name     | Type                                                   | Description                        |
| -------- | ------------------------------------------------------ | ---------------------------------- |
| `params` | struct SinglePositionQuickSwapStrategy.ImmutableParams | immutable parameters to be checked |

#### checkTickDeviations

```solidity
  function checkTickDeviations(struct SinglePositionQuickSwapStrategy.ImmutableParams immutableParams_, struct SinglePositionQuickSwapStrategy.MutableParams mutableParams_, contract IAlgebraPool vaultPool) public
```

📕 checks deviation of spot ticks of all pools in strategy from corresponding average ticks. If any deviation is large than maxDevation parameter for the pool, then the transaction will be reverted with a LIMIT\_OVERFLOW error. If there are no observations 10 seconds ago in any of the considered pools, then the transaction will be reverted with an INVALID\_STATE error.

**Parameters:**

| Name               | Type                                                   | Description                                         |
| ------------------ | ------------------------------------------------------ | --------------------------------------------------- |
| `immutableParams_` | struct SinglePositionQuickSwapStrategy.ImmutableParams | structure with all immutable params of the strategy |
| `mutableParams_`   | struct SinglePositionQuickSwapStrategy.MutableParams   | structure with all mutable params of the strategy   |
| `vaultPool`        | contract IAlgebraPool                                  | UniswapV3Pool of quickSwapVault                     |

#### calculateTargetRatioOfToken1

```solidity
  function calculateTargetRatioOfToken1(struct SinglePositionQuickSwapStrategy.Interval interval, uint160 sqrtSpotPriceX96, uint256 spotPriceX96) public returns (uint256 targetRatioOfToken1X96)
```

📕 calculate target ratio of token 1 to total capital after rebalance

**Parameters:**

| Name               | Type                                            | Description                        |
| ------------------ | ----------------------------------------------- | ---------------------------------- |
| `interval`         | struct SinglePositionQuickSwapStrategy.Interval | current interval on quickSwapVault |
| `sqrtSpotPriceX96` | uint160                                         | sqrt price X96 of spot tick        |
| `spotPriceX96`     | uint256                                         | price X96 of spot tick             |

**Return Values:**

| Name                     | Type    | Description                         |
| ------------------------ | ------- | ----------------------------------- |
| `targetRatioOfToken1X96` | uint256 | ratio of token 1 multiplied by 2^96 |

#### calculateAmountsForSwap

```solidity
  function calculateAmountsForSwap(struct SinglePositionQuickSwapStrategy.ImmutableParams immutableParams_, struct SinglePositionQuickSwapStrategy.MutableParams mutableParams_, uint256 priceX96, uint256 targetRatioOfToken1X96) public returns (uint256 tokenInIndex, uint256 amountIn)
```

📕 notion link: <https://www.notion.so/mellowprotocol/Swap-formula-53807cbf5c5641eda937dd1847d70f43> calculates the token that needs to be swapped and its amount to get the target ratio of tokens in the erc20Vault.

**Parameters:**

| Name                     | Type                                                   | Description                                              |
| ------------------------ | ------------------------------------------------------ | -------------------------------------------------------- |
| `immutableParams_`       | struct SinglePositionQuickSwapStrategy.ImmutableParams | structure with all immutable params of the strategy      |
| `mutableParams_`         | struct SinglePositionQuickSwapStrategy.MutableParams   | structure with all mutable params of the strategy        |
| `priceX96`               | uint256                                                | price X96 of spot tick                                   |
| `targetRatioOfToken1X96` | uint256                                                | target ratio of token 1 to total capital after rebalance |

**Return Values:**

| Name           | Type    | Description              |
| -------------- | ------- | ------------------------ |
| `tokenInIndex` | uint256 | swap token index         |
| `amountIn`     | uint256 | number of tokens to swap |

#### depositCallback

```solidity
  function depositCallback() external
```

Function, that ERC20RootVault calling after deposit

#### withdrawCallback

```solidity
  function withdrawCallback() external
```

Function, that ERC20RootVault calling after withdraw

### Structs

```solidity
struct ImmutableParams {
    address router;
    IERC20Vault erc20Vault;
    IQuickSwapVault quickSwapVault;
    address[] tokens;
}
```

```solidity
struct MutableParams {
    uint24 feeTierOfPoolOfAuxiliaryAnd0Tokens;
    uint24 feeTierOfPoolOfAuxiliaryAnd1Tokens;
    int24 priceImpactD6;
    int24 intervalWidth;
    int24 tickNeighborhood;
    int24 maxDeviationForVaultPool;
    int24 maxDeviationForPoolOfAuxiliaryAnd0Tokens;
    int24 maxDeviationForPoolOfAuxiliaryAnd1Tokens;
    uint32 timespanForAverageTick;
    address auxiliaryToken;
    uint256 amount0Desired;
    uint256 amount1Desired;
    uint256 swapSlippageD;
    uint256[] minSwapAmounts;
}
```

```solidity
struct Interval {
    int24 lowerTick;
    int24 upperTick;
}
```

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### TokensSwapped

```solidity
  event TokensSwapped(struct ISwapRouter.ExactInputParams swapParams, uint256 amountOut)
```

Emitted after a successful token swap

**Parameters:**

| Name         | Type                                | Description                                                          |
| ------------ | ----------------------------------- | -------------------------------------------------------------------- |
| `swapParams` | struct ISwapRouter.ExactInputParams | structure with different parameters for handling swap via swapRouter |
| `amountOut`  | uint256                             | the actual amount received from the swapRouter during swaps          |

#### UpdateMutableParams

```solidity
  event UpdateMutableParams(address origin, address sender, struct SinglePositionQuickSwapStrategy.MutableParams mutableParams)
```

Emited when mutable parameters are successfully updated

**Parameters:**

| Name            | Type                                                 | Description                           |
| --------------- | ---------------------------------------------------- | ------------------------------------- |
| `origin`        | address                                              | Origin of the transaction (tx.origin) |
| `sender`        | address                                              | Sender of the call (msg.sender)       |
| `mutableParams` | struct SinglePositionQuickSwapStrategy.MutableParams | Updated parameters                    |

#### Rebalance

```solidity
  event Rebalance(address origin, address sender)
```

Emited when the rebalance is successfully completed

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |

#### PositionMinted

```solidity
  event PositionMinted(uint256 tokenId)
```

Emited when a new uniswap position is created

**Parameters:**

| Name      | Type    | Description                 |
| --------- | ------- | --------------------------- |
| `tokenId` | uint256 | nft of new uniswap position |

#### PositionBurned

```solidity
  event PositionBurned(uint256 tokenId)
```

Emited when a uniswap position is burned

**Parameters:**

| Name      | Type    | Description             |
| --------- | ------- | ----------------------- |
| `tokenId` | uint256 | nft of uniswap position |

## SinglePositionStrategy

*Inherits from* [*DefaultAccessControlLateInit*](#defaultaccesscontrollateinit)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)*,* [*Multicall*](#multicall)*,* [*ContractMeta*](#contractmeta)

⛽ 7.31M

### Functions

#### constructor

```solidity
  function constructor(contract INonfungiblePositionManager positionManager_) public
```

**Parameters:**

| Name               | Type                                 | Description                           |
| ------------------ | ------------------------------------ | ------------------------------------- |
| `positionManager_` | contract INonfungiblePositionManager | Uniswap v3 NonfungiblePositionManager |

**Specs**

* ✅ creates contract

#### initialize

⛽ 671K

```solidity
  function initialize(struct SinglePositionStrategy.ImmutableParams immutableParams_, address admin) external
```

**Parameters:**

| Name               | Type                                          | Description                                         |
| ------------------ | --------------------------------------------- | --------------------------------------------------- |
| `immutableParams_` | struct SinglePositionStrategy.ImmutableParams | structure with all immutable params of the strategy |
| `admin`            | address                                       | admin of the strategy                               |

#### updateMutableParams

⛽ 120K (89K - 245K)

```solidity
  function updateMutableParams(struct SinglePositionStrategy.MutableParams mutableParams_) external
```

📕 updates mutable params of the strategy. Only the admin can call the function

**Parameters:**

| Name             | Type                                        | Description       |
| ---------------- | ------------------------------------------- | ----------------- |
| `mutableParams_` | struct SinglePositionStrategy.MutableParams | new params to set |

#### rebalance

⛽ 1.16M (804K - 1.38M)

```solidity
  function rebalance(uint256 deadline) external
```

📕 Rebalancing goes like this:

1. Function checks the current states of the pools, and if the volatility is significant, the transaction reverts.
2. If necessary, a new position is minted on uniV3Vault, and the previous one is burned.
3. Tokens on erc20Vault are swapped via swapRouter so that the proportion matches the tokens on uniV3Vault.
4. The strategy transfers all possible tokens from erc20Vault to uniV3Vault. Only users with administrator or operator roles can call the function.

**Parameters:**

| Name       | Type    | Description                                          |
| ---------- | ------- | ---------------------------------------------------- |
| `deadline` | uint256 | Timestamp by which the transaction must be completed |

**Specs**

* ✅ works correctly

#### calculateNewInterval

```solidity
  function calculateNewInterval(struct SinglePositionStrategy.MutableParams mutableParams_, int24 tick, contract IUniswapV3Pool pool) public returns (int24 lowerTick, int24 upperTick)
```

📕 calculates a new interval according to the mutable params, the tickSpacing of the pool and the spot tick

**Parameters:**

| Name             | Type                                        | Description                                               |
| ---------------- | ------------------------------------------- | --------------------------------------------------------- |
| `mutableParams_` | struct SinglePositionStrategy.MutableParams | structure with all mutable params of the strategy         |
| `tick`           | int24                                       | current spot tick of the pool                             |
| `pool`           | contract IUniswapV3Pool                     | the UniV3Vault pool where the new position will be minted |

**Return Values:**

| Name        | Type  | Description                    |
| ----------- | ----- | ------------------------------ |
| `lowerTick` | int24 | lower tick of the new interval |
| `upperTick` | int24 | upper tick of the new interval |

#### checkMutableParams

```solidity
  function checkMutableParams(struct SinglePositionStrategy.MutableParams params, struct SinglePositionStrategy.ImmutableParams immutableParams_) public
```

📕 checks mutable params according to strategy restrictions

**Parameters:**

| Name               | Type                                          | Description                                         |
| ------------------ | --------------------------------------------- | --------------------------------------------------- |
| `params`           | struct SinglePositionStrategy.MutableParams   | mutable parameters to be checked                    |
| `immutableParams_` | struct SinglePositionStrategy.ImmutableParams | structure with all immutable params of the strategy |

#### checkImmutableParams

```solidity
  function checkImmutableParams(struct SinglePositionStrategy.ImmutableParams params) public
```

📕 checks immutable params according to strategy restrictions

**Parameters:**

| Name     | Type                                          | Description                        |
| -------- | --------------------------------------------- | ---------------------------------- |
| `params` | struct SinglePositionStrategy.ImmutableParams | immutable parameters to be checked |

#### checkTickDeviations

```solidity
  function checkTickDeviations(struct SinglePositionStrategy.ImmutableParams immutableParams_, struct SinglePositionStrategy.MutableParams mutableParams_, contract IUniswapV3Pool vaultPool) public
```

📕 checks deviation of spot ticks of all pools in strategy from corresponding average ticks. If any deviation is large than maxDevation parameter for the pool, then the transaction will be reverted with a LIMIT\_OVERFLOW error. If there are no observations 10 seconds ago in any of the considered pools, then the transaction will be reverted with an INVALID\_STATE error.

**Parameters:**

| Name               | Type                                          | Description                                         |
| ------------------ | --------------------------------------------- | --------------------------------------------------- |
| `immutableParams_` | struct SinglePositionStrategy.ImmutableParams | structure with all immutable params of the strategy |
| `mutableParams_`   | struct SinglePositionStrategy.MutableParams   | structure with all mutable params of the strategy   |
| `vaultPool`        | contract IUniswapV3Pool                       | UniswapV3Pool of uniV3Vault                         |

#### calculateTargetRatioOfToken1

```solidity
  function calculateTargetRatioOfToken1(struct SinglePositionStrategy.Interval interval, uint160 sqrtSpotPriceX96, uint256 spotPriceX96) public returns (uint256 targetRatioOfToken1X96)
```

📕 calculate target ratio of token 1 to total capital after rebalance

**Parameters:**

| Name               | Type                                   | Description                    |
| ------------------ | -------------------------------------- | ------------------------------ |
| `interval`         | struct SinglePositionStrategy.Interval | current interval on uniV3Vault |
| `sqrtSpotPriceX96` | uint160                                | sqrt price X96 of spot tick    |
| `spotPriceX96`     | uint256                                | price X96 of spot tick         |

**Return Values:**

| Name                     | Type    | Description                         |
| ------------------------ | ------- | ----------------------------------- |
| `targetRatioOfToken1X96` | uint256 | ratio of token 1 multiplied by 2^96 |

#### calculateAmountsForSwap

```solidity
  function calculateAmountsForSwap(struct SinglePositionStrategy.ImmutableParams immutableParams_, struct SinglePositionStrategy.MutableParams mutableParams_, uint256 priceX96, uint256 targetRatioOfToken1X96) public returns (uint256 tokenInIndex, uint256 amountIn)
```

📕 notion link: <https://www.notion.so/mellowprotocol/Swap-formula-53807cbf5c5641eda937dd1847d70f43> calculates the token that needs to be swapped and its amount to get the target ratio of tokens in the erc20Vault.

**Parameters:**

| Name                     | Type                                          | Description                                              |
| ------------------------ | --------------------------------------------- | -------------------------------------------------------- |
| `immutableParams_`       | struct SinglePositionStrategy.ImmutableParams | structure with all immutable params of the strategy      |
| `mutableParams_`         | struct SinglePositionStrategy.MutableParams   | structure with all mutable params of the strategy        |
| `priceX96`               | uint256                                       | price X96 of spot tick                                   |
| `targetRatioOfToken1X96` | uint256                                       | target ratio of token 1 to total capital after rebalance |

**Return Values:**

| Name           | Type    | Description              |
| -------------- | ------- | ------------------------ |
| `tokenInIndex` | uint256 | swap token index         |
| `amountIn`     | uint256 | number of tokens to swap |

#### depositCallback

```solidity
  function depositCallback() external
```

Function, that ERC20RootVault calling after deposit

#### withdrawCallback

```solidity
  function withdrawCallback() external
```

Function, that ERC20RootVault calling after withdraw

### Structs

```solidity
struct ImmutableParams {
    address router;
    IERC20Vault erc20Vault;
    IUniV3Vault uniV3Vault;
    address[] tokens;
}
```

```solidity
struct MutableParams {
    uint24 feeTierOfPoolOfAuxiliaryAnd0Tokens;
    uint24 feeTierOfPoolOfAuxiliaryAnd1Tokens;
    int24 priceImpactD6;
    int24 intervalWidth;
    int24 tickNeighborhood;
    int24 maxDeviationForVaultPool;
    int24 maxDeviationForPoolOfAuxiliaryAnd0Tokens;
    int24 maxDeviationForPoolOfAuxiliaryAnd1Tokens;
    uint32 timespanForAverageTick;
    address auxiliaryToken;
    uint256 amount0Desired;
    uint256 amount1Desired;
    uint256 swapSlippageD;
    uint256[] minSwapAmounts;
}
```

```solidity
struct Interval {
    int24 lowerTick;
    int24 upperTick;
}
```

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### TokensSwapped

```solidity
  event TokensSwapped(struct ISwapRouter.ExactInputParams swapParams, uint256 amountOut)
```

Emitted after a successful token swap

**Parameters:**

| Name         | Type                                | Description                                                          |
| ------------ | ----------------------------------- | -------------------------------------------------------------------- |
| `swapParams` | struct ISwapRouter.ExactInputParams | structure with different parameters for handling swap via swapRouter |
| `amountOut`  | uint256                             | the actual amount received from the swapRouter during swaps          |

#### UpdateMutableParams

```solidity
  event UpdateMutableParams(address origin, address sender, struct SinglePositionStrategy.MutableParams mutableParams)
```

Emited when mutable parameters are successfully updated

**Parameters:**

| Name            | Type                                        | Description                           |
| --------------- | ------------------------------------------- | ------------------------------------- |
| `origin`        | address                                     | Origin of the transaction (tx.origin) |
| `sender`        | address                                     | Sender of the call (msg.sender)       |
| `mutableParams` | struct SinglePositionStrategy.MutableParams | Updated parameters                    |

#### Rebalance

```solidity
  event Rebalance(address origin, address sender)
```

Emited when the rebalance is successfully completed

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |

#### PositionMinted

```solidity
  event PositionMinted(uint256 tokenId)
```

Emited when a new uniswap position is created

**Parameters:**

| Name      | Type    | Description                 |
| --------- | ------- | --------------------------- |
| `tokenId` | uint256 | nft of new uniswap position |

#### PositionBurned

```solidity
  event PositionBurned(uint256 tokenId)
```

Emited when a uniswap position is burned

**Parameters:**

| Name      | Type    | Description             |
| --------- | ------- | ----------------------- |
| `tokenId` | uint256 | nft of uniswap position |

## BatchCall

⛽ 435K

#### batchcall

⛽ 23K

```solidity
  function batchcall(address[] targets, bytes[] data) external returns (bytes[] results)
```

**Specs**

* ✅ returns results
* ✅ edge cases: when arrays have different lengths reverts with INVL
* ✅ edge cases: when targets arrays not only of contracts reverts with "Address: delegate call to non-contract"

## ContractMeta

#### contractName

```solidity
  function contractName() external returns (string)
```

#### contractNameBytes

```solidity
  function contractNameBytes() external returns (bytes32)
```

#### contractVersion

```solidity
  function contractVersion() external returns (string)
```

#### contractVersionBytes

```solidity
  function contractVersionBytes() external returns (bytes32)
```

## DefaultAccessControl

*Inherits from* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)

⛽ 1.35M

This is a default access control with 3 roles:

* ADMIN: allowed to do anything
* ADMIN\_DELEGATE: allowed to do anything except assigning ADMIN and ADMIN\_DELEGATE roles
* OPERATOR: low-privileged role, generally keeper or some other bot

### Functions

#### constructor

```solidity
  function constructor(address admin) public
```

Creates a new contract.

**Parameters:**

| Name    | Type    | Description           |
| ------- | ------- | --------------------- |
| `admin` | address | Admin of the contract |

#### isAdmin

```solidity
  function isAdmin(address sender) public returns (bool)
```

Checks if the address is ADMIN or ADMIN\_DELEGATE.

**Parameters:**

| Name     | Type    | Description       |
| -------- | ------- | ----------------- |
| `sender` | address | Adddress to check |

**Return Values:**

| Name | Type | Description                           |
| ---- | ---- | ------------------------------------- |
| `if` | bool | sender is an admin, `false` otherwise |

#### isOperator

```solidity
  function isOperator(address sender) public returns (bool)
```

Checks if the address is OPERATOR.

**Parameters:**

| Name     | Type    | Description       |
| -------- | ------- | ----------------- |
| `sender` | address | Adddress to check |

**Return Values:**

| Name | Type | Description                           |
| ---- | ---- | ------------------------------------- |
| `if` | bool | sender is an admin, `false` otherwise |

### Structs

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

## DefaultAccessControlLateInit

*Inherits from* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)

⛽ 1.25M

This is a default access control with 3 roles:

* ADMIN: allowed to do anything
* ADMIN\_DELEGATE: allowed to do anything except assigning ADMIN and ADMIN\_DELEGATE roles
* OPERATOR: low-privileged role, generally keeper or some other bot

### Functions

#### isAdmin

```solidity
  function isAdmin(address sender) public returns (bool)
```

Checks that the address is contract admin.

**Parameters:**

| Name  | Type    | Description      |
| ----- | ------- | ---------------- |
| `who` | address | Address to check |

**Return Values:**

| Name | Type | Description                     |
| ---- | ---- | ------------------------------- |
| `if` | bool | who is admin, `false` otherwise |

**Specs**

* ✅ returns `true` if sender is an admin, `false` otherwise

#### isOperator

```solidity
  function isOperator(address sender) public returns (bool)
```

Checks that the address is contract admin.

**Parameters:**

| Name  | Type    | Description      |
| ----- | ------- | ---------------- |
| `who` | address | Address to check |

**Return Values:**

| Name | Type | Description                        |
| ---- | ---- | ---------------------------------- |
| `if` | bool | who is operator, `false` otherwise |

**Specs**

* ✅ returns `true` if sender is an operator, `false` otherwise

#### init

⛽ 301K

```solidity
  function init(address admin) public
```

Initializes a new contract with roles and single ADMIN.

**Parameters:**

| Name    | Type    | Description           |
| ------- | ------- | --------------------- |
| `admin` | address | Admin of the contract |

### Structs

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

## DefaultProxy

*Inherits from* [*TransparentUpgradeableProxy*](#transparentupgradeableproxy)*,* [*ERC1967Proxy*](#erc1967proxy)*,* [*ERC1967Upgrade*](#erc1967upgrade)*,* [*Proxy*](#proxy)

#### constructor

```solidity
  function constructor(address _logic, address admin_, bytes _data) public
```

## DefaultProxyAdmin

*Inherits from* [*ProxyAdmin*](#proxyadmin)*,* [*Ownable*](#ownable)*,* [*Context*](#context)

## ERC20RootVaultHelper

⛽ 445K

#### getTvlToken0

```solidity
  function getTvlToken0(uint256[] tvls, address[] tokens, contract IOracle oracle) external returns (uint256 tvl0)
```

## ERC20Token

⛽ 1.01M

#### DOMAIN\_SEPARATOR

```solidity
  function DOMAIN_SEPARATOR() public returns (bytes32)
```

**Specs**

* ✅ returns domaint separator

#### approve

```solidity
  function approve(address spender, uint256 amount) public returns (bool)
```

**Specs**

* ✅ allows `sender` to transfer `spender` an `amount` and emits Approval

#### transfer

```solidity
  function transfer(address to, uint256 amount) public returns (bool)
```

**Specs**

* ✅ transfers `amount` from `msg.sender` to `to`
* ✅ rom transfers `amount` from `from` to `to` if allowed

#### transferFrom

```solidity
  function transferFrom(address from, address to, uint256 amount) public returns (bool)
```

**Specs**

* ✅ transfers `amount` from `from` to `to` if allowed

#### permit

```solidity
  function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public
```

**Specs**

* ✅ emits Approval
* ✅ edge cases: when deadline less than current timestamp reverts with TS
* ✅ edge cases: when incorrect signature reverts with FRB

## GearboxHelper

### Functions

#### setParameters

```solidity
  function setParameters(contract ICreditFacade creditFacade_, contract ICreditManagerV2 creditManager_, address curveAdapter_, address convexAdapter_, address primaryToken_, address depositToken_, uint256 nft_) external
```

#### verifyInstances

```solidity
  function verifyInstances() external returns (int128 primaryIndex, address convexOutputToken, uint256 poolId)
```

#### calculateEarnedCvxAmountByEarnedCrvAmount

```solidity
  function calculateEarnedCvxAmountByEarnedCrvAmount(uint256 crvAmount, address cvxTokenAddress) public returns (uint256)
```

#### calculateClaimableRewards

```solidity
  function calculateClaimableRewards(address creditAccount, address vaultGovernance) public returns (uint256)
```

#### calculateDesiredTotalValue

```solidity
  function calculateDesiredTotalValue(address creditAccount, address vaultGovernance, uint256 marginalFactorD9) external returns (uint256 expectedAllAssetsValue, uint256 currentAllAssetsValue)
```

#### calcConvexTokensToWithdraw

```solidity
  function calcConvexTokensToWithdraw(uint256 desiredValueNominatedUnderlying, address creditAccount, address convexOutputToken) public returns (uint256)
```

#### calcRateRAY

```solidity
  function calcRateRAY(address tokenFrom, address tokenTo) public returns (uint256)
```

#### calculateAmountInMaximum

```solidity
  function calculateAmountInMaximum(address fromToken, address toToken, uint256 amount, uint256 maxSlippageD9) public returns (uint256)
```

#### createUniswapMulticall

```solidity
  function createUniswapMulticall(address tokenFrom, address tokenTo, uint256 fee, address adapter, uint256 slippage) public returns (struct MultiCall)
```

#### checkNecessaryDepositExchange

```solidity
  function checkNecessaryDepositExchange(uint256 expectedMaximalDepositTokenValueNominatedUnderlying, address vaultGovernance, address creditAccount) public
```

#### claimRewards

```solidity
  function claimRewards(address vaultGovernance, address creditAccount, address convexOutputToken) public
```

#### withdrawFromConvex

```solidity
  function withdrawFromConvex(uint256 amount, address vaultGovernance, int128 primaryIndex) public
```

#### depositToConvex

```solidity
  function depositToConvex(struct MultiCall debtManagementCall, struct IGearboxVaultGovernance.DelayedProtocolParams protocolParams, uint256 poolId, int128 primaryIndex) public
```

#### adjustPosition

```solidity
  function adjustPosition(uint256 expectedAllAssetsValue, uint256 currentAllAssetsValue, address vaultGovernance, uint256 marginalFactorD9, int128 primaryIndex, uint256 poolId, address convexOutputToken, address creditAccount_) external
```

#### swapExactOutput

```solidity
  function swapExactOutput(address fromToken, address toToken, uint256 amount, uint256 untouchableSum, address vaultGovernance, address creditAccount) external
```

#### pullFromAddress

```solidity
  function pullFromAddress(uint256 amount, address vaultGovernance) external returns (uint256[] actualAmounts)
```

#### openCreditAccount

```solidity
  function openCreditAccount(address creditAccount, address vaultGovernance, uint256 marginalFactorD9) external
```

### Events

#### CreditAccountOpened

```solidity
  event CreditAccountOpened(address origin, address sender, address creditAccount)
```

Emitted when a credit account linked to this vault is opened in Gearbox

**Parameters:**

| Name            | Type    | Description                           |
| --------------- | ------- | ------------------------------------- |
| `origin`        | address | Origin of the transaction (tx.origin) |
| `sender`        | address | Sender of the call (msg.sender)       |
| `creditAccount` | address | Address of the opened credit account  |

#### PositionAdjusted

```solidity
  event PositionAdjusted(address origin, address sender, uint256 newTotalAssetsValue)
```

Emitted when an adjusment of the position made in Gearbox

**Parameters:**

| Name                  | Type    | Description                                               |
| --------------------- | ------- | --------------------------------------------------------- |
| `origin`              | address | Origin of the transaction (tx.origin)                     |
| `sender`              | address | Sender of the call (msg.sender)                           |
| `newTotalAssetsValue` | uint256 | New value of all assets (debt + real assets) of the vault |

## HStrategyHelper

⛽ 3.26M

#### calculateExpectedRatios

```solidity
  function calculateExpectedRatios(struct HStrategy.DomainPositionParams domainPositionParams) external returns (struct HStrategy.ExpectedRatios ratios)
```

calculates the ratios of the capital on all vaults using price from the oracle

**Parameters:**

| Name                   | Type                                  | Description                                                   |
| ---------------------- | ------------------------------------- | ------------------------------------------------------------- |
| `domainPositionParams` | struct HStrategy.DomainPositionParams | the current state of the position, pool and oracle prediction |

**Return Values:**

| Name     | Type                            | Description           |
| -------- | ------------------------------- | --------------------- |
| `ratios` | struct HStrategy.ExpectedRatios | ratios of the capital |

#### calculateMissingTokenAmounts

```solidity
  function calculateMissingTokenAmounts(contract IIntegrationVault moneyVault, struct HStrategy.TokenAmounts expectedTokenAmounts, struct HStrategy.DomainPositionParams domainPositionParams, uint128 liquidity) external returns (struct HStrategy.TokenAmounts missingTokenAmounts)
```

calculates amount of missing tokens for uniV3 and money vaults

**Parameters:**

| Name                   | Type                                  | Description                                                               |
| ---------------------- | ------------------------------------- | ------------------------------------------------------------------------- |
| `moneyVault`           | contract IIntegrationVault            | the strategy money vault                                                  |
| `expectedTokenAmounts` | struct HStrategy.TokenAmounts         | the amount of tokens we expect after rebalance                            |
| `domainPositionParams` | struct HStrategy.DomainPositionParams | current position and pool state combined with predictions from the oracle |
| `liquidity`            | uint128                               | current liquidity in position                                             |

**Return Values:**

| Name                  | Type                          | Description               |
| --------------------- | ----------------------------- | ------------------------- |
| `missingTokenAmounts` | struct HStrategy.TokenAmounts | amounts of missing tokens |

#### calculateExtraTokenAmountsForUniV3Vault

```solidity
  function calculateExtraTokenAmountsForUniV3Vault(struct HStrategy.TokenAmounts expectedTokenAmounts, struct HStrategy.DomainPositionParams domainPositionParams) external returns (uint256[] tokenAmounts)
```

calculates extra tokens on uniV3 vault

**Parameters:**

| Name                   | Type                                  | Description                                                               |
| ---------------------- | ------------------------------------- | ------------------------------------------------------------------------- |
| `expectedTokenAmounts` | struct HStrategy.TokenAmounts         | the amount of tokens we expect after rebalance                            |
| `domainPositionParams` | struct HStrategy.DomainPositionParams | current position and pool state combined with predictions from the oracle |

**Return Values:**

| Name           | Type       | Description                       |
| -------------- | ---------- | --------------------------------- |
| `tokenAmounts` | uint256\[] | extra token amounts on UniV3Vault |

#### calculateExtraTokenAmountsForMoneyVault

```solidity
  function calculateExtraTokenAmountsForMoneyVault(contract IIntegrationVault moneyVault, struct HStrategy.TokenAmounts expectedTokenAmounts) external returns (uint256[] tokenAmounts)
```

calculates extra tokens on money vault

**Parameters:**

| Name                   | Type                          | Description                                    |
| ---------------------- | ----------------------------- | ---------------------------------------------- |
| `moneyVault`           | contract IIntegrationVault    | the strategy money vault                       |
| `expectedTokenAmounts` | struct HStrategy.TokenAmounts | the amount of tokens we expect after rebalance |

**Return Values:**

| Name           | Type       | Description                       |
| -------------- | ---------- | --------------------------------- |
| `tokenAmounts` | uint256\[] | extra token amounts on MoneyVault |

#### calculateExpectedTokenAmountsByExpectedRatios

```solidity
  function calculateExpectedTokenAmountsByExpectedRatios(struct HStrategy.ExpectedRatios expectedRatios, struct HStrategy.TokenAmountsInToken0 expectedTokenAmountsInToken0, struct HStrategy.DomainPositionParams domainPositionParams, contract UniV3Helper uniV3Helper) external returns (struct HStrategy.TokenAmounts amounts)
```

calculates expected amounts of tokens after rebalance

**Parameters:**

| Name                           | Type                                  | Description                                                               |
| ------------------------------ | ------------------------------------- | ------------------------------------------------------------------------- |
| `expectedRatios`               | struct HStrategy.ExpectedRatios       | ratios of the capital on different assets                                 |
| `expectedTokenAmountsInToken0` | struct HStrategy.TokenAmountsInToken0 | expected capitals (in token0) on the strategy vaults                      |
| `domainPositionParams`         | struct HStrategy.DomainPositionParams | current position and pool state combined with predictions from the oracle |
| `uniV3Helper`                  | contract UniV3Helper                  | helper for uniswap V3 calculations                                        |

**Return Values:**

| Name      | Type                          | Description                                                       |
| --------- | ----------------------------- | ----------------------------------------------------------------- |
| `amounts` | struct HStrategy.TokenAmounts | amounts of tokens expected after rebalance on the strategy vaults |

#### calculateCurrentTokenAmounts

```solidity
  function calculateCurrentTokenAmounts(contract IIntegrationVault erc20Vault, contract IIntegrationVault moneyVault, struct HStrategy.DomainPositionParams params) external returns (struct HStrategy.TokenAmounts amounts)
```

calculates current amounts of tokens

**Parameters:**

| Name         | Type                                  | Description                                                               |
| ------------ | ------------------------------------- | ------------------------------------------------------------------------- |
| `erc20Vault` | contract IIntegrationVault            | the erc20 vault of the strategy                                           |
| `moneyVault` | contract IIntegrationVault            | the money vault of the strategy                                           |
| `params`     | struct HStrategy.DomainPositionParams | current position and pool state combined with predictions from the oracle |

**Return Values:**

| Name      | Type                          | Description       |
| --------- | ----------------------------- | ----------------- |
| `amounts` | struct HStrategy.TokenAmounts | amounts of tokens |

#### calculateCurrentCapitalInToken0

```solidity
  function calculateCurrentCapitalInToken0(struct HStrategy.DomainPositionParams params, struct HStrategy.TokenAmounts currentTokenAmounts) external returns (uint256 capital)
```

calculates current capital of the strategy in token0

**Parameters:**

| Name                  | Type                                  | Description                                                               |
| --------------------- | ------------------------------------- | ------------------------------------------------------------------------- |
| `params`              | struct HStrategy.DomainPositionParams | current position and pool state combined with predictions from the oracle |
| `currentTokenAmounts` | struct HStrategy.TokenAmounts         | amounts of the tokens on the erc20 and money vaults                       |

**Return Values:**

| Name      | Type    | Description                      |
| --------- | ------- | -------------------------------- |
| `capital` | uint256 | total capital measured in token0 |

#### calculateExpectedTokenAmountsInToken0

```solidity
  function calculateExpectedTokenAmountsInToken0(uint256 totalCapitalInToken0, struct HStrategy.ExpectedRatios expectedRatios, struct HStrategy.RatioParams ratioParams_) external returns (struct HStrategy.TokenAmountsInToken0 amounts)
```

calculates expected capitals on the vaults after rebalance

**Parameters:**

| Name                   | Type                            | Description                                                                                                  |
| ---------------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `totalCapitalInToken0` | uint256                         | total capital in token0                                                                                      |
| `expectedRatios`       | struct HStrategy.ExpectedRatios | ratios of the capitals on the vaults expected after rebalance                                                |
| `ratioParams_`         | struct HStrategy.RatioParams    | ratio of the tokens between erc20 and money vault combined with needed deviations for rebalance to be called |

**Return Values:**

| Name      | Type                                  | Description                                          |
| --------- | ------------------------------------- | ---------------------------------------------------- |
| `amounts` | struct HStrategy.TokenAmountsInToken0 | capitals expected after rebalance measured in token0 |

#### swapNeeded

```solidity
  function swapNeeded(struct HStrategy.TokenAmounts currentTokenAmounts, struct HStrategy.TokenAmounts expectedTokenAmounts, struct HStrategy.RatioParams ratioParams, struct HStrategy.DomainPositionParams domainPositionParams) external returns (bool needed)
```

return true if the token swap is needed. It is needed if we cannot mint a new position without it

**Parameters:**

| Name                   | Type                                  | Description                                                                                                  |
| ---------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `currentTokenAmounts`  | struct HStrategy.TokenAmounts         | the amounts of tokens on the vaults                                                                          |
| `expectedTokenAmounts` | struct HStrategy.TokenAmounts         | the amounts of tokens expected after rebalancing                                                             |
| `ratioParams`          | struct HStrategy.RatioParams          | ratio of the tokens between erc20 and money vault combined with needed deviations for rebalance to be called |
| `domainPositionParams` | struct HStrategy.DomainPositionParams | the current state of the position, pool and oracle prediction                                                |

**Return Values:**

| Name     | Type | Description                      |
| -------- | ---- | -------------------------------- |
| `needed` | bool | true if the token swap is needed |

#### tokenRebalanceNeeded

```solidity
  function tokenRebalanceNeeded(struct HStrategy.TokenAmounts currentTokenAmounts, struct HStrategy.TokenAmounts expectedTokenAmounts, struct HStrategy.RatioParams ratioParams) external returns (bool needed)
```

returns true if the rebalance between assets on different vaults is needed

**Parameters:**

| Name                   | Type                          | Description                                                                                                  |
| ---------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `currentTokenAmounts`  | struct HStrategy.TokenAmounts | the current amounts of tokens on the vaults                                                                  |
| `expectedTokenAmounts` | struct HStrategy.TokenAmounts | the amounts of tokens expected after rebalance                                                               |
| `ratioParams`          | struct HStrategy.RatioParams  | ratio of the tokens between erc20 and money vault combined with needed deviations for rebalance to be called |

**Return Values:**

| Name     | Type | Description                     |
| -------- | ---- | ------------------------------- |
| `needed` | bool | true if the rebalance is needed |

#### calculateAndCheckDomainPositionParams

```solidity
  function calculateAndCheckDomainPositionParams(int24 tick, struct HStrategy.StrategyParams strategyParams_, uint256 uniV3Nft, contract INonfungiblePositionManager positionManager_) external returns (struct HStrategy.DomainPositionParams params)
```

**Parameters:**

| Name               | Type                                 | Description                                   |
| ------------------ | ------------------------------------ | --------------------------------------------- |
| `tick`             | int24                                | current price tick                            |
| `strategyParams_`  | struct HStrategy.StrategyParams      | the current parameters of the strategy        |
| `uniV3Nft`         | uint256                              | the nft of the position from position manager |
| `positionManager_` | contract INonfungiblePositionManager | the position manager for uniV3                |

#### checkSpotTickDeviationFromAverage

```solidity
  function checkSpotTickDeviationFromAverage(int24 tick, address pool_, struct HStrategy.OracleParams oracleParams_, contract UniV3Helper uniV3Helper) external
```

**Parameters:**

| Name            | Type                          | Description                        |
| --------------- | ----------------------------- | ---------------------------------- |
| `tick`          | int24                         | current price tick                 |
| `pool_`         | address                       | address of uniV3 pool              |
| `oracleParams_` | struct HStrategy.OracleParams | oracle parameters                  |
| `uniV3Helper`   | contract UniV3Helper          | helper for uniswap V3 calculations |

#### calculateNewPositionTicks

```solidity
  function calculateNewPositionTicks(int24 spotTick, struct HStrategy.StrategyParams strategyParams_) external returns (int24 lowerTick, int24 upperTick)
```

**Parameters:**

| Name              | Type                            | Description            |
| ----------------- | ------------------------------- | ---------------------- |
| `spotTick`        | int24                           | current price tick     |
| `strategyParams_` | struct HStrategy.StrategyParams | parameters of strategy |

**Return Values:**

| Name        | Type  | Description                |
| ----------- | ----- | -------------------------- |
| `lowerTick` | int24 | lower tick of new position |
| `upperTick` | int24 | upper tick of new position |

#### calculateExpectedTokenAmounts

```solidity
  function calculateExpectedTokenAmounts(struct HStrategy.TokenAmounts currentTokenAmounts, struct HStrategy.DomainPositionParams domainPositionParams, contract HStrategyHelper hStrategyHelper_, contract UniV3Helper uniV3Helper, struct HStrategy.RatioParams ratioParams) external returns (struct HStrategy.TokenAmounts expectedTokenAmounts)
```

**Parameters:**

| Name                   | Type                                  | Description                                                   |
| ---------------------- | ------------------------------------- | ------------------------------------------------------------- |
| `currentTokenAmounts`  | struct HStrategy.TokenAmounts         | current token amounts on vaults in both tokens                |
| `domainPositionParams` | struct HStrategy.DomainPositionParams | the current state of the position, pool and oracle prediction |
| `hStrategyHelper_`     | contract HStrategyHelper              | address of HStrategyHelper                                    |
| `uniV3Helper`          | contract UniV3Helper                  | helper for uniswap V3 calculations                            |
| `ratioParams`          | struct HStrategy.RatioParams          | ratio parameters                                              |

**Return Values:**

| Name                   | Type                          | Description                                          |
| ---------------------- | ----------------------------- | ---------------------------------------------------- |
| `expectedTokenAmounts` | struct HStrategy.TokenAmounts | expected amounts of tokens after rebalance on vaults |

## LStrategyHelper

⛽ 1.5M

#### constructor

```solidity
  function constructor(address cowswap_) public
```

#### checkOrder

```solidity
  function checkOrder(struct GPv2Order.Data order, bytes uuid, address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut, uint256 deadline, address erc20Vault, uint256 fee) external
```

#### tickFromPriceX96

```solidity
  function tickFromPriceX96(uint256 priceX96) external returns (int24)
```

## MultiPoolHStrategyRebalancer

*Inherits from* [*DefaultAccessControlLateInit*](#defaultaccesscontrollateinit)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)

⛽ 7.09M

### Functions

#### constructor

```solidity
  function constructor(contract INonfungiblePositionManager positionManager_) public
```

constructs a rebalancer

**Parameters:**

| Name               | Type                                 | Description                           |
| ------------------ | ------------------------------------ | ------------------------------------- |
| `positionManager_` | contract INonfungiblePositionManager | Uniswap V3 NonfungiblePositionManager |

#### initialize

```solidity
  function initialize(address strategy) external
```

initializes the rebalancer

**Parameters:**

| Name       | Type    | Description                                    |
| ---------- | ------- | ---------------------------------------------- |
| `strategy` | address | address of the strategy for current rebalancer |

#### createRebalancer

```solidity
  function createRebalancer(address strategy) external returns (contract MultiPoolHStrategyRebalancer rebalancer)
```

creates the clone of the rebalancer

**Parameters:**

| Name       | Type    | Description                                |
| ---------- | ------- | ------------------------------------------ |
| `strategy` | address | address of the strategy for new rebalancer |

**Return Values:**

| Name         | Type                                  | Description                              |
| ------------ | ------------------------------------- | ---------------------------------------- |
| `rebalancer` | contract MultiPoolHStrategyRebalancer | new cloned rebalancer for given strategy |

#### getTvls

```solidity
  function getTvls(struct MultiPoolHStrategyRebalancer.StrategyData data) public returns (struct MultiPoolHStrategyRebalancer.Tvls tvls)
```

**Parameters:**

| Name   | Type                                             | Description                                                               |
| ------ | ------------------------------------------------ | ------------------------------------------------------------------------- |
| `data` | struct MultiPoolHStrategyRebalancer.StrategyData | structure with all immutable, mutable and internal params of the strategy |

#### processRebalance

```solidity
  function processRebalance(struct MultiPoolHStrategyRebalancer.StrategyData data, struct MultiPoolHStrategyRebalancer.Restrictions restrictions) external returns (struct MultiPoolHStrategyRebalancer.Restrictions actualAmounts)
```

**Parameters:**

| Name           | Type                                             | Description                                                               |
| -------------- | ------------------------------------------------ | ------------------------------------------------------------------------- |
| `data`         | struct MultiPoolHStrategyRebalancer.StrategyData | structure with all immutable, mutable and internal params of the strategy |
| `restrictions` | struct MultiPoolHStrategyRebalancer.Restrictions | rebalance restrictions                                                    |

#### calculateExpectedAmounts

```solidity
  function calculateExpectedAmounts(struct MultiPoolHStrategyRebalancer.StrategyData data, uint160 sqrtPriceX96, uint256 totalToken0, uint256 totalToken1) public returns (uint256[] moneyExpected, uint256[][] uniV3Expected, uint256 expectedAmountOfToken0)
```

**Parameters:**

| Name           | Type                                             | Description                                                            |
| -------------- | ------------------------------------------------ | ---------------------------------------------------------------------- |
| `sqrtPriceX96` | struct MultiPoolHStrategyRebalancer.StrategyData | sqrt prices X96 at lower and upper ticks of domain and short intervals |
| `sqrtPriceX96` | uint160                                          | sqrt price X96 at current spot tick in swapPool                        |
| `totalToken0`  | uint256                                          | current actual amount of token 0 in the root vault system              |
| `totalToken1`  | uint256                                          | current actual amount of token 1 in the root vault system              |

#### calculateNewPosition

```solidity
  function calculateNewPosition(struct MultiPoolHStrategyRebalancer.StrategyData data, int24 tick) public returns (int24 newShortLowerTick, int24 newShortUpperTick)
```

**Parameters:**

| Name   | Type                                             | Description                                                               |
| ------ | ------------------------------------------------ | ------------------------------------------------------------------------- |
| `data` | struct MultiPoolHStrategyRebalancer.StrategyData | structure with all immutable, mutable and internal params of the strategy |
| `tick` | int24                                            | current spot tick of swapPool                                             |

### Structs

```solidity
struct StrategyData {
    int24 halfOfShortInterval;
    int24 domainLowerTick;
    int24 domainUpperTick;
    int24 shortLowerTick;
    int24 shortUpperTick;
    int24 maxTickDeviation;
    uint32 averageTickTimespan;
    IERC20Vault erc20Vault;
    IIntegrationVault moneyVault;
    IUniswapV3Pool swapPool;
    address router;
    uint256 amount0ForMint;
    uint256 amount1ForMint;
    uint256 erc20CapitalRatioD;
    uint256[] uniV3Weights;
    address[] tokens;
    IUniV3Vault[] uniV3Vaults;
}
```

```solidity
struct Tvls {
    uint256[] money;
    uint256[][] uniV3;
    uint256[] erc20;
    uint256[] total;
    uint256[] totalUniV3;
}
```

```solidity
struct SqrtRatios {
    uint160 sqrtShortLowerX96;
    uint160 sqrtShortUpperX96;
    uint160 sqrtDomainLowerX96;
    uint160 sqrtDomainUpperX96;
}
```

```solidity
struct Restrictions {
    int24 newShortLowerTick;
    int24 newShortUpperTick;
    int256[] swappedAmounts;
    uint256[][] drainedAmounts;
    uint256[][] pulledToUniV3;
    uint256[][] pulledFromUniV3;
    uint256 deadline;
}
```

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### PositionsMinted

```solidity
  event PositionsMinted(uint256[] uniV3Nfts)
```

Emitted when new short positions minted in uniV3Vaults

**Parameters:**

| Name        | Type       | Description              |
| ----------- | ---------- | ------------------------ |
| `uniV3Nfts` | uint256\[] | nfts of minted positions |

#### PositionsBurned

```solidity
  event PositionsBurned(uint256[] uniV3Nfts)
```

Emitted when old short positions burned in uniV3Vaults

**Parameters:**

| Name        | Type       | Description              |
| ----------- | ---------- | ------------------------ |
| `uniV3Nfts` | uint256\[] | nfts of burned positions |

#### TokensSwapped

```solidity
  event TokensSwapped(struct ISwapRouter.ExactInputSingleParams swapParams, uint256 amountOut)
```

Emitted when a swap is called on the router

**Parameters:**

| Name         | Type                                      | Description                                      |
| ------------ | ----------------------------------------- | ------------------------------------------------ |
| `swapParams` | struct ISwapRouter.ExactInputSingleParams | parameters to process swap with UniswapV3 router |
| `amountOut`  | uint256                                   | recived amount of token during the swap          |

## PulseStrategyHelper

#### getStrategyParams

```solidity
  function getStrategyParams(contract PulseStrategy strategy) public returns (struct PulseStrategy.ImmutableParams immutableParams, struct PulseStrategy.MutableParams mutableParams)
```

#### calculateAmountForSwap

```solidity
  function calculateAmountForSwap(contract PulseStrategy strategy) public returns (uint256 amountIn, address from, address to, contract IERC20Vault erc20Vault)
```

## PulseStrategyV2Helper

#### getStrategyParams

```solidity
  function getStrategyParams(contract PulseStrategyV2 strategy) public returns (struct PulseStrategyV2.ImmutableParams immutableParams, struct PulseStrategyV2.MutableParams mutableParams)
```

#### calculateAmountForSwap

```solidity
  function calculateAmountForSwap(contract PulseStrategyV2 strategy) public returns (uint256 amountIn, address from, address to, contract IERC20Vault erc20Vault)
```

## QuickPulseStrategyHelper

#### getStrategyParams

```solidity
  function getStrategyParams(contract QuickPulseStrategy strategy) public returns (struct QuickPulseStrategy.ImmutableParams immutableParams, struct QuickPulseStrategy.MutableParams mutableParams)
```

#### calculateAmountForSwap

```solidity
  function calculateAmountForSwap(contract QuickPulseStrategy strategy) public returns (uint256 amountIn, address from, address to, contract IERC20Vault erc20Vault)
```

## QuickSwapHelper

#### constructor

```solidity
  function constructor(contract IAlgebraNonfungiblePositionManager positionManager_, address quickToken_, address dQuickToken_) public
```

#### calculateTvl

```solidity
  function calculateTvl(uint256 nft, struct IQuickSwapVaultGovernance.StrategyParams strategyParams, contract IFarmingCenter farmingCenter, address token0) public returns (uint256[] tokenAmounts)
```

#### liquidityToTokenAmounts

```solidity
  function liquidityToTokenAmounts(uint256 nft, uint160 sqrtRatioX96, uint128 liquidity) public returns (uint256 amount0, uint256 amount1)
```

#### tokenAmountsToLiquidity

```solidity
  function tokenAmountsToLiquidity(uint256 nft, uint160 sqrtRatioX96, uint256[] amounts) public returns (uint128 liquidity)
```

#### tokenAmountsToMaxLiquidity

```solidity
  function tokenAmountsToMaxLiquidity(uint256 nft, uint160 sqrtRatioX96, uint256[] amounts) public returns (uint128 liquidity)
```

#### calculateLiquidityToPull

```solidity
  function calculateLiquidityToPull(uint256 nft, uint160 sqrtRatioX96, uint256[] tokenAmounts) public returns (uint128 liquidity)
```

#### increaseCumulative

```solidity
  function increaseCumulative(uint32 currentTimestamp, contract IAlgebraEternalVirtualPool virtualPool) public returns (uint256 deltaTotalRewardGrowth0, uint256 deltaTotalRewardGrowth1)
```

#### calculateInnerFeesGrow

```solidity
  function calculateInnerFeesGrow(contract IAlgebraEternalVirtualPool virtualPool, int24 tickLower, int24 tickUpper) public returns (uint256 virtualPoolInnerRewardGrowth0, uint256 virtualPoolInnerRewardGrowth1)
```

#### calculateCollectableRewards

```solidity
  function calculateCollectableRewards(contract IAlgebraEternalFarming farming, struct IIncentiveKey.IncentiveKey key, uint256 nft) public returns (uint256 rewardAmount, uint256 bonusRewardAmount)
```

#### convertTokenToUnderlying

```solidity
  function convertTokenToUnderlying(uint256 amount, address from, address to, uint32 timespan) public returns (uint256)
```

## SinglePositionStrategyHelper

#### checkUniV3PoolState

```solidity
  function checkUniV3PoolState(address pool, int24 maxDeviation, uint32 timespan) public
```

#### checkAlgebraPoolState

```solidity
  function checkAlgebraPoolState(address pool, int24 maxDeviation, uint32 timespan) public
```

## UniV3Helper

⛽ 2.82M

#### constructor

```solidity
  function constructor(contract INonfungiblePositionManager positionManager_) public
```

#### liquidityToTokenAmounts

```solidity
  function liquidityToTokenAmounts(uint128 liquidity, contract IUniswapV3Pool pool, uint256 uniV3Nft) external returns (uint256[] tokenAmounts)
```

**Specs**

* ✅ returns correct vaulues for type(uint128).max

#### tokenAmountsToLiquidity

```solidity
  function tokenAmountsToLiquidity(uint256[] tokenAmounts, contract IUniswapV3Pool pool, uint256 uniV3Nft) external returns (uint128 liquidity)
```

#### tokenAmountsToMaximalLiquidity

```solidity
  function tokenAmountsToMaximalLiquidity(uint160 sqrtRatioX96, int24 tickLower, int24 tickUpper, uint256 amount0, uint256 amount1) external returns (uint128 liquidity)
```

#### getPoolByNft

```solidity
  function getPoolByNft(uint256 uniV3Nft) public returns (contract IUniswapV3Pool pool)
```

📕 returns with "Invalid Token ID" for non-existent nfts

#### getFeesByNft

```solidity
  function getFeesByNft(uint256 uniV3Nft) external returns (uint256 fees0, uint256 fees1)
```

📕 returns with "Invalid Token ID" for non-existent nfts

#### calculateTvlBySqrtPriceX96

```solidity
  function calculateTvlBySqrtPriceX96(uint256 uniV3Nft, uint160 sqrtPriceX96) public returns (uint256[] tokenAmounts)
```

📕 returns with "Invalid Token ID" for non-existent nfts

#### calculateTvlByMinMaxPrices

```solidity
  function calculateTvlByMinMaxPrices(uint256 uniV3Nft, uint256 minPriceX96, uint256 maxPriceX96) external returns (uint256[] minTokenAmounts, uint256[] maxTokenAmounts)
```

📕 returns with "Invalid Token ID" for non-existent nfts

#### getTickDeviationForTimeSpan

```solidity
  function getTickDeviationForTimeSpan(int24 tick, address pool_, uint32 secondsAgo) external returns (bool withFail, int24 deviation)
```

**Specs**

* ✅ returns withFail=true if there is no observation in the pool that was not made before secondsAgo

#### getPositionTokenAmountsByCapitalOfToken0

```solidity
  function getPositionTokenAmountsByCapitalOfToken0(uint256 lowerPriceSqrtX96, uint256 upperPriceSqrtX96, uint256 spotPriceForSqrtFormulasX96, uint256 spotPriceX96, uint256 capital) external returns (uint256 token0Amount, uint256 token1Amount)
```

📕 calculates the distribution of tokens that can be added to the position after swap for given capital in token 0

**Specs**

* ✅ test uniV3Helper, borders: -600 0
* ✅ test uniV3Helper, borders: 600 1200
* ✅ test uniV3Helper, borders: -600 600

## WhiteList

*Inherits from* [*DefaultAccessControl*](#defaultaccesscontrol)*,* [*AccessControlEnumerable*](#accesscontrolenumerable)*,* [*AccessControl*](#accesscontrol)*,* [*ERC165*](#erc165)*,* [*Context*](#context)

⛽ 2.49M

### Functions

#### constructor

```solidity
  function constructor(address admin) public
```

#### deposit

⛽ 483K

```solidity
  function deposit(contract IERC20RootVault vault, uint256[] tokenAmounts, uint256 minLpTokens, bytes vaultOptions, bytes32[] proof) external returns (uint256[] actualTokenAmounts)
```

**Specs**

* ✅ works correctly
* ✅ reverts on wrong address

#### updateRoot

⛽ 47K

```solidity
  function updateRoot(bytes32 root_) external
```

### Structs

```solidity
struct RoleData {
    mapping(address => bool) members;
    bytes32 adminRole;
}
```

### Events

#### Deposit

```solidity
  event Deposit(address from, address to, address[] tokens, uint256[] actualTokenAmounts, uint256 lpTokenMinted)
```

Emitted when liquidity is deposited

**Parameters:**

| Name                 | Type       | Description                                  |
| -------------------- | ---------- | -------------------------------------------- |
| `from`               | address    | The source address for the liquidity         |
| `tokens`             | address    | ERC20 tokens deposited                       |
| `actualTokenAmounts` | address\[] | Token amounts deposited                      |
| `lpTokenMinted`      | uint256\[] | LP tokens received by the liquidity provider |

## AllowAllValidator

*Inherits from* [*Validator*](#validator)*,* [*BaseValidator*](#basevalidator)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 851K

### Functions

#### constructor

```solidity
  function constructor(contract IProtocolGovernance protocolGovernance_) public
```

**Specs**

* ✅ deploys a new contract

#### validate

```solidity
  function validate(address, address, uint256, bytes4, bytes) external
```

**Specs**

* ✅ successful validate

### Structs

```solidity
struct ValidatorParams {
    IProtocolGovernance protocolGovernance;
}
```

## BaseValidator

### Functions

#### constructor

```solidity
  function constructor(contract IProtocolGovernance protocolGovernance) public
```

#### stagedValidatorParams

```solidity
  function stagedValidatorParams() external returns (struct IBaseValidator.ValidatorParams)
```

Validator params staged to commit.

#### stagedValidatorParamsTimestamp

```solidity
  function stagedValidatorParamsTimestamp() external returns (uint256)
```

Timestamp after which validator params can be committed.

#### validatorParams

```solidity
  function validatorParams() external returns (struct IBaseValidator.ValidatorParams)
```

Current validator params.

#### stageValidatorParams

```solidity
  function stageValidatorParams(struct IBaseValidator.ValidatorParams newParams) external
```

Stages params that could have been committed after governance delay expires.

**Parameters:**

| Name        | Type                                  | Description     |
| ----------- | ------------------------------------- | --------------- |
| `newParams` | struct IBaseValidator.ValidatorParams | Params to stage |

#### commitValidatorParams

```solidity
  function commitValidatorParams() external
```

Commits staged params

### Structs

```solidity
struct ValidatorParams {
    IProtocolGovernance protocolGovernance;
}
```

### Events

#### StagedValidatorParams

```solidity
  event StagedValidatorParams(address origin, address sender, struct IBaseValidator.ValidatorParams newParams, uint256 when)
```

Emitted when new params are staged for commit

**Parameters:**

| Name        | Type                                  | Description                            |
| ----------- | ------------------------------------- | -------------------------------------- |
| `origin`    | address                               | Origin of the transaction (tx.origin)  |
| `sender`    | address                               | Sender of the call (msg.sender)        |
| `newParams` | struct IBaseValidator.ValidatorParams | New params that were staged for commit |
| `when`      | uint256                               | When the params could be committed     |

#### CommittedValidatorParams

```solidity
  event CommittedValidatorParams(address origin, address sender, struct IBaseValidator.ValidatorParams params)
```

Emitted when new params are staged for commit

**Parameters:**

| Name     | Type                                  | Description                            |
| -------- | ------------------------------------- | -------------------------------------- |
| `origin` | address                               | Origin of the transaction (tx.origin)  |
| `sender` | address                               | Sender of the call (msg.sender)        |
| `params` | struct IBaseValidator.ValidatorParams | New params that were staged for commit |

## CowswapValidator

*Inherits from* [*Validator*](#validator)*,* [*BaseValidator*](#basevalidator)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 909K

### Functions

#### constructor

```solidity
  function constructor(contract IProtocolGovernance protocolGovernance_) public
```

**Specs**

* ✅ deploys a new contract

#### validate

```solidity
  function validate(address, address, uint256, bytes4 selector, bytes) external
```

**Specs**

* ✅ successful validate
* ✅ edge cases: when selector is not 0xec6cb13f reverts with INVS

### Structs

```solidity
struct ValidatorParams {
    IProtocolGovernance protocolGovernance;
}
```

## CurveValidator

*Inherits from* [*Validator*](#validator)*,* [*BaseValidator*](#basevalidator)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 1.14M

### Functions

#### constructor

```solidity
  function constructor(contract IProtocolGovernance protocolGovernance_) public
```

**Specs**

* ✅ deploys a new contract

#### validate

```solidity
  function validate(address, address addr, uint256, bytes4 selector, bytes data) external
```

**Specs**

* ✅ successful validate
* ✅ edge cases: when selector is not 0x3df02124 reverts with INVS
* ✅ edge cases: when token ids are equal reverts with INV
* ✅ edge cases: when not a vault token reverts with INVTO
* ✅ edge cases: when pool has no approve permission reverts with FRB

### Structs

```solidity
struct ValidatorParams {
    IProtocolGovernance protocolGovernance;
}
```

## ERC20Validator

*Inherits from* [*Validator*](#validator)*,* [*BaseValidator*](#basevalidator)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 1.14M

### Functions

#### constructor

```solidity
  function constructor(contract IProtocolGovernance protocolGovernance_) public
```

**Specs**

* ✅ deploys a new contract

#### validate

```solidity
  function validate(address sender, address addr, uint256 value, bytes4 selector, bytes data) external
```

**Specs**

* ✅ successful validate, spender can approve
* ✅ successful validate, sender is trusted strategy
* ✅ edge cases: when value is not zero reverts with INV
* ✅ edge cases: when selector is not 0x095ea7b3 reverts with INVS
* ✅ edge cases: when no transfer permission reverts with FRB
* ✅ edge cases: when no approve permission reverts with FRB

### Structs

```solidity
struct ValidatorParams {
    IProtocolGovernance protocolGovernance;
}
```

## QuickSwapValidator

*Inherits from* [*Validator*](#validator)*,* [*BaseValidator*](#basevalidator)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

### Functions

#### constructor

```solidity
  function constructor(contract IProtocolGovernance protocolGovernance_, address swapRouter_, contract IAlgebraFactory factory_) public
```

#### validate

```solidity
  function validate(address, address addr, uint256 value, bytes4 selector, bytes data) external
```

### Structs

```solidity
struct ValidatorParams {
    IProtocolGovernance protocolGovernance;
}
```

## UniV2Validator

*Inherits from* [*Validator*](#validator)*,* [*BaseValidator*](#basevalidator)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 1.58M

### Functions

#### constructor

```solidity
  function constructor(contract IProtocolGovernance protocolGovernance_, address swapRouter_, contract IUniswapV2Factory factory_) public
```

**Specs**

* ✅ deploys a new contract

#### validate

```solidity
  function validate(address, address addr, uint256 value, bytes4 selector, bytes data) external
```

**Specs**

* ✅ selector is 0x7ff36ab5 or 0xfb3bdb41 successful validate
* ✅ selector is 0x7ff36ab5 or 0xfb3bdb41 edge cases: when addr is not swap reverts with INVTR
* ✅ selector is 0x7ff36ab5 or 0xfb3bdb41 edge cases: when selector is wrong reverts with INVS
* ✅ selector is 0x7ff36ab5 or 0xfb3bdb41 edge cases: when path is too small reverts with INVL
* ✅ selector is 0x7ff36ab5 or 0xfb3bdb41 edge cases: when not a vault token reverts with INVTO
* ✅ selector is 0x7ff36ab5 or 0xfb3bdb41 edge cases: when tokens are the same reverts with INVTO
* ✅ selector is 0x7ff36ab5 or 0xfb3bdb41 edge cases: when pool has no approve permission reverts with FRB
* ✅ selector is 0x7ff36ab5 or 0xfb3bdb41 edge cases: when sender is not a reciever reverts
* ✅ selector is one of: 0x4a25d94a, 0x18cbafe5, 0x38ed1739, 0x8803dbee successful validate
* ✅ selector is one of: 0x4a25d94a, 0x18cbafe5, 0x38ed1739, 0x8803dbee edge cases: when value is not zero reverts with INV
* ✅ selector is one of: 0x4a25d94a, 0x18cbafe5, 0x38ed1739, 0x8803dbee edge cases: when sender is not reciever reverts
* ✅ selector is one of: 0x4a25d94a, 0x18cbafe5, 0x38ed1739, 0x8803dbee edge cases: when path too small reverts with INVL
* ✅ selector is one of: 0x4a25d94a, 0x18cbafe5, 0x38ed1739, 0x8803dbee edge cases: when not a vault token reverts with INVTO
* ✅ selector is one of: 0x4a25d94a, 0x18cbafe5, 0x38ed1739, 0x8803dbee edge cases: when tokens are the same reverts with INVTO
* ✅ selector is one of: 0x4a25d94a, 0x18cbafe5, 0x38ed1739, 0x8803dbee edge cases: when pool has no approve permission reverts with FRB

### Structs

```solidity
struct TokenInput {
    uint256 amount;
    uint256 amountMax;
    address[] path;
    address to;
    uint256 deadline;
}
```

```solidity
struct EthInput {
    uint256 amountMax;
    address[] path;
    address to;
    uint256 deadline;
}
```

```solidity
struct ValidatorParams {
    IProtocolGovernance protocolGovernance;
}
```

## UniV3Validator

*Inherits from* [*Validator*](#validator)*,* [*BaseValidator*](#basevalidator)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 1.75M

### Functions

#### constructor

```solidity
  function constructor(contract IProtocolGovernance protocolGovernance_, address swapRouter_, contract IUniswapV3Factory factory_) public
```

**Specs**

* ✅ deploys a new contract

#### validate

```solidity
  function validate(address, address addr, uint256 value, bytes4 selector, bytes data) external
```

**Specs**

* ✅ edge cases: if addr is not swap reverts with INVTR
* ✅ edge cases: if value is not zero reverts with INV
* ✅ edge cases: if selector is wrong reverts with INVS
* ✅ selector is 0x414bf389 successful validate
* ✅ selector is 0x414bf389 edge cases: if recipient is not sender reverts with INVTR
* ✅ selector is 0x414bf389 edge cases: if not a vault token reverts with INVTO
* ✅ selector is 0x414bf389 edge cases: if tokens are the same reverts with INVTO
* ✅ selector is 0x414bf389 edge cases: if pool has no permisson reverts with FRB
* ✅ selector is 0xdb3e2198 successfull validate
* ✅ selector is 0xdb3e2198 edge cases: if recipient is not sender reverts with INVTR
* ✅ selector is 0xdb3e2198 edge cases: if not a vault token reverts with INVTO
* ✅ selector is 0xdb3e2198 edge cases: if tokens are the same reverts with INVTO
* ✅ selector is 0xdb3e2198 edge cases: if pool has no permisson reverts with FRB
* ✅ selector is 0xc04b8d59 successfull validate
* ✅ selector is 0xc04b8d59 edge cases: if recipient is not sender reverts with INVTR
* ✅ selector is 0xc04b8d59 edge cases: if tokens are the same reverts with INVTO
* ✅ selector is 0xc04b8d59 edge cases: if pool has no approve permission reverts with FRB
* ✅ selector is 0xc04b8d59 edge cases: if not a vault token reverts with INVTO
* ✅ selector is 0xf28c0498 successfull validate
* ✅ selector is 0xf28c0498 edge cases: if recipient is not sender reverts with INVTR
* ✅ selector is 0xf28c0498 edge cases: if tokens are the same reverts with INVTO
* ✅ selector is 0xf28c0498 edge cases: if pool has no approve permission reverts with FRB
* ✅ selector is 0xf28c0498 edge cases: if not a vault token reverts with INVTO

### Structs

```solidity
struct ValidatorParams {
    IProtocolGovernance protocolGovernance;
}
```

## Validator

*Inherits from* [*BaseValidator*](#basevalidator)*,* [*ERC165*](#erc165)

### Functions

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

### Structs

```solidity
struct ValidatorParams {
    IProtocolGovernance protocolGovernance;
}
```

## AaveVault

*Inherits from* [*Vault*](#vault)*,* [*ERC165*](#erc165)*,* [*ReentrancyGuard*](#reentrancyguard)

⛽ 4.96M

Vault that interfaces Aave protocol in the integration layer.

📕 Notes: **TVL**

The TVL of the vault is cached and updated after each deposit withdraw. So essentially `tvl` call doesn't take into account accrued interest / donations to Aave since the last `deposit` / `withdraw`

**aTokens** aTokens are fixed at the token creation and addresses are taken from Aave Lending Pool. So essentially each aToken is fixed for life of the AaveVault. If the aToken is missing for some vaultToken, the AaveVault cannot be created.

**Push / Pull** It is assumed that any amounts of tokens can be deposited / withdrawn from Aave. The contract's vaultTokens are fully allowed to Aave Lending Pool.

#### tvl

```solidity
  function tvl() public returns (uint256[] minTokenAmounts, uint256[] maxTokenAmounts)
```

Total value locked for this contract.

📕 Generally it is the underlying token value of this contract in some other DeFi protocol. For example, for USDC Yearn Vault this would be total USDC balance that could be withdrawn for Yearn to this contract. The tvl itself is estimated in some range. Sometimes the range is exact, sometimes it's not

**Return Values:**

| Name              | Type       | Description                                                                                                   |
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| `minTokenAmounts` | uint256\[] | Lower bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |
| `maxTokenAmounts` | uint256\[] | Upper bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |

**Specs**

* ✅ returns total value locked
* ✅ returns total value locked, no time passed from initialization
* ✅ edge cases: when there are no initial funds returns zeroes

#### lendingPool

```solidity
  function lendingPool() external returns (contract ILendingPool)
```

Reference to Aave protocol lending pool.

**Specs**

* ✅ returns ILendingPool
* ✅ access control: allowed: any address

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true if this contract supports 0x18026500 interface
* ✅ access control: allowed: any address
* ✅ returns true if this contract supports 0x7a63aa3a interface
* ✅ access control: allowed: any address
* ✅ edge cases: when contract does not support the given interface returns false

#### updateTvls

⛽ 94K (93K - 95K)

```solidity
  function updateTvls() external
```

Update all tvls to current aToken balances.

**Specs**

* ✅ updates total value locked

#### initialize

⛽ 200K (159K - 245K)

```solidity
  function initialize(uint256 nft_, address[] vaultTokens_) external
```

Initialized a new contract.

📕 Can only be initialized by vault governance

**Parameters:**

| Name           | Type       | Description                                     |
| -------------- | ---------- | ----------------------------------------------- |
| `nft_`         | uint256    | NFT of the vault in the VaultRegistry           |
| `vaultTokens_` | address\[] | ERC20 tokens that will be managed by this Vault |

**Specs**

* ✅ emits Initialized event
* ✅ initializes contract successfully
* ✅ edge cases: when vault's nft is not 0 reverts with INIT
* ✅ edge cases: when tokens are not sorted reverts with INVA
* ✅ edge cases: when tokens are not unique reverts with INVA
* ✅ edge cases: when setting zero nft reverts with VZ
* ✅ edge cases: when setting token with address zero reverts with AZ
* ✅ edge cases: when token has no permission to become a vault token reverts with FRB

## AaveVaultGovernance

*Inherits from* [*VaultGovernance*](#vaultgovernance)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 2.31M

Governance that manages all Aave Vaults params and can deploy a new Aave Vault.

### Functions

#### constructor

```solidity
  function constructor(struct IVaultGovernance.InternalParams internalParams_, struct IAaveVaultGovernance.DelayedProtocolParams delayedProtocolParams_) public
```

Creates a new contract.

**Parameters:**

| Name                     | Type                                              | Description             |
| ------------------------ | ------------------------------------------------- | ----------------------- |
| `internalParams_`        | struct IVaultGovernance.InternalParams            | Initial Internal Params |
| `delayedProtocolParams_` | struct IAaveVaultGovernance.DelayedProtocolParams | Initial Protocol Params |

**Specs**

* ✅ deploys a new contract
* ✅ initializes internalParams

*Edge cases*

* ✅ when lendingPool address is 0 reverts
* ✅ when estimatedAaveAPY is 0 reverts
* ✅ when estimatedAaaveAPY is larger than limit reverts
* ✅ when protocolGovernance address is 0 reverts
* ✅ when vaultRegistry address is 0 reverts

#### delayedProtocolParams

```solidity
  function delayedProtocolParams() public returns (struct IAaveVaultGovernance.DelayedProtocolParams)
```

Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Specs**

* ✅ returns current DelayedProtocolParams

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ staging DelayedProtocolParams doesn't change delayedProtocolParams

*Edge cases*

* ✅ when no params were committed returns non-zero params initialized in constructor

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true if this contract supports 0x2f8c3ff3 interface
* ✅ access control: allowed: any address

#### stagedDelayedProtocolParams

```solidity
  function stagedDelayedProtocolParams() external returns (struct IAaveVaultGovernance.DelayedProtocolParams)
```

Delayed Protocol Params staged for commit after delay.

**Specs**

* ✅ returns DelayedProtocolParams staged for commit

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ always equals to params that were just staged

*Edge cases*

* ✅ when no params are staged for commit returns zero struct
* ✅ when params were just committed returns zero struct

#### stageDelayedProtocolParams

⛽ 88K (52K - 129K)

```solidity
  function stageDelayedProtocolParams(struct IAaveVaultGovernance.DelayedProtocolParams params) external
```

Stage Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

📕 Can only be called after delayedProtocolParamsTimestamp.

**Parameters:**

| Name     | Type                                              | Description |
| -------- | ------------------------------------------------- | ----------- |
| `params` | struct IAaveVaultGovernance.DelayedProtocolParams | New params  |

**Specs**

* ✅ stages DelayedProtocolParams for commit
* ✅ sets delay for commit
* ✅ emits StageDelayedProtocolParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ denied: Vault NFT Owner (aka liquidity provider)
* ✅ denied: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address

*Edge cases*

* ✅ when estimated Aave APY is larger than limit reverts
* ✅ when called twice succeeds with the last value
* ✅ when called with zero params reverts with zero params

#### commitDelayedProtocolParams

⛽ 50K (49K - 54K)

```solidity
  function commitDelayedProtocolParams() external
```

Commit Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Specs**

* ✅ commits staged DelayedProtocolParams
* ✅ resets delay for commit
* ✅ emits CommitDelayedProtocolParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ denied: Vault NFT Owner (aka liquidity provider)
* ✅ denied: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address
* ✅ reverts if called before the delay has elapsed
* ✅ succeeds if called after the delay has elapsed

*Edge cases*

* ✅ when called twice reverts
* ✅ when nothing is staged reverts
* ✅ when delay has not elapsed reverts

#### createVault

⛽ 729K (665K - 942K)

```solidity
  function createVault(address[] vaultTokens_, address owner_) external returns (contract IAaveVault vault, uint256 nft)
```

Deploys a new vault.

**Parameters:**

| Name           | Type       | Description                                     |
| -------------- | ---------- | ----------------------------------------------- |
| `vaultTokens_` | address\[] | ERC20 tokens that will be managed by this Vault |
| `owner_`       | address    | Owner of the vault NFT                          |

**Specs**

* ✅ deploys a new vault
* ✅ registers vault with vault registry and issues nft
* ✅ the nft is owned by the owner from #createVault arguments
* ✅ vault is initialized with nft

*Access control*

* ✅ when permissionless allowed: any address
* ✅ when not permissionless allowed: protocol governance admin
* ✅ when not permissionless denied: any address

### Structs

```solidity
struct DelayedProtocolParams {
    ILendingPool lendingPool;
    uint256 estimatedAaveAPY;
}
```

```solidity
struct InternalParams {
    IProtocolGovernance protocolGovernance;
    IVaultRegistry registry;
    IVault singleton;
}
```

### Events

#### StageDelayedProtocolParams

```solidity
  event StageDelayedProtocolParams(address origin, address sender, struct IAaveVaultGovernance.DelayedProtocolParams params, uint256 when)
```

Emitted when new DelayedProtocolParams are staged for commit

**Parameters:**

| Name     | Type                                              | Description                            |
| -------- | ------------------------------------------------- | -------------------------------------- |
| `origin` | address                                           | Origin of the transaction (tx.origin)  |
| `sender` | address                                           | Sender of the call (msg.sender)        |
| `params` | struct IAaveVaultGovernance.DelayedProtocolParams | New params that were staged for commit |
| `when`   | uint256                                           | When the params could be committed     |

#### CommitDelayedProtocolParams

```solidity
  event CommitDelayedProtocolParams(address origin, address sender, struct IAaveVaultGovernance.DelayedProtocolParams params)
```

Emitted when new DelayedProtocolParams are committed

**Parameters:**

| Name     | Type                                              | Description                           |
| -------- | ------------------------------------------------- | ------------------------------------- |
| `origin` | address                                           | Origin of the transaction (tx.origin) |
| `sender` | address                                           | Sender of the call (msg.sender)       |
| `params` | struct IAaveVaultGovernance.DelayedProtocolParams | New params that are committed         |

## AggregateVault

*Inherits from* [*Vault*](#vault)*,* [*ERC165*](#erc165)

Vault that combines several integration layer Vaults into one Vault.

#### subvaultNfts

```solidity
  function subvaultNfts() external returns (uint256[])
```

Get all subvalutNfts in the current Vault

**Return Values:**

| Name           | Type       | Description       |
| -------------- | ---------- | ----------------- |
| `subvaultNfts` | uint256\[] | Subvaults of NTFs |

#### subvaultOneBasedIndex

```solidity
  function subvaultOneBasedIndex(uint256 nft_) external returns (uint256)
```

Get index of subvault by nft

**Parameters:**

| Name   | Type    | Description              |
| ------ | ------- | ------------------------ |
| `nft_` | uint256 | Nft for getting subvault |

**Return Values:**

| Name    | Type    | Description       |
| ------- | ------- | ----------------- |
| `index` | uint256 | Index of subvault |

#### hasSubvault

```solidity
  function hasSubvault(uint256 nft_) external returns (bool)
```

Checks if subvault is present

**Parameters:**

| Name   | Type    | Description                 |
| ------ | ------- | --------------------------- |
| `nft_` | uint256 | index of subvault for check |

**Return Values:**

| Name | Type | Description                         |
| ---- | ---- | ----------------------------------- |
| `if` | bool | subvault present, `false` otherwise |

#### subvaultAt

```solidity
  function subvaultAt(uint256 index) external returns (address)
```

Get subvault by index

**Parameters:**

| Name    | Type    | Description       |
| ------- | ------- | ----------------- |
| `index` | uint256 | Index of subvault |

**Return Values:**

| Name      | Type    | Description             |
| --------- | ------- | ----------------------- |
| `address` | address | Address of the contract |

#### tvl

```solidity
  function tvl() public returns (uint256[] minTokenAmounts, uint256[] maxTokenAmounts)
```

Total value locked for this contract.

📕 Generally it is the underlying token value of this contract in some other DeFi protocol. For example, for USDC Yearn Vault this would be total USDC balance that could be withdrawn for Yearn to this contract. The tvl itself is estimated in some range. Sometimes the range is exact, sometimes it's not

**Return Values:**

| Name              | Type       | Description                                                                                                   |
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| `minTokenAmounts` | uint256\[] | Lower bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |
| `maxTokenAmounts` | uint256\[] | Upper bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

## ERC20RootVault

*Inherits from* [*AggregateVault*](#aggregatevault)*,* [*Vault*](#vault)*,* [*ERC165*](#erc165)*,* [*ReentrancyGuard*](#reentrancyguard)*,* [*ERC20Token*](#erc20token)

⛽ 7.12M

Contract that mints and burns LP tokens in exchange for ERC20 liquidity.

### Functions

#### depositorsAllowlist

```solidity
  function depositorsAllowlist() external returns (address[])
```

List of addresses of depositors from which interaction with private vaults is allowed

**Specs**

* ✅ returns non zero length of depositorsAllowlist
* ✅ access control: allowed: any address

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true if this contract supports 0x23040f0a interface
* ✅ edge cases: when contract does not support the given interface returns false
* ✅ access control: allowed: any address

#### addDepositorsToAllowlist

⛽ 112K (22K - 126K)

```solidity
  function addDepositorsToAllowlist(address[] depositors) external
```

Add new depositors in the depositorsAllowlist

📕 The action can be done only by user with admins, owners or by approved rights

**Parameters:**

| Name         | Type       | Description             |
| ------------ | ---------- | ----------------------- |
| `depositors` | address\[] | Array of new depositors |

**Specs**

* ✅ adds depositor to allow list
* ✅ access control: allowed: admin
* ✅ access control: not allowed: deployer
* ✅ access control: not allowed: any address

#### removeDepositorsFromAllowlist

⛽ 50K (49K - 53K)

```solidity
  function removeDepositorsFromAllowlist(address[] depositors) external
```

Remove depositors from the depositorsAllowlist

📕 The action can be done only by user with admins, owners or by approved rights

**Parameters:**

| Name         | Type       | Description                    |
| ------------ | ---------- | ------------------------------ |
| `depositors` | address\[] | Array of depositors for remove |

**Specs**

* ✅ removes depositor to allow list
* ✅ access control: allowed: admin
* ✅ access control: not allowed: deployer
* ✅ access control: not allowed: any address

#### initialize

```solidity
  function initialize(uint256 nft_, address[] vaultTokens_, address strategy_, uint256[] subvaultNfts_, contract IERC20RootVaultHelper helper_) external
```

Initialized a new contract.

📕 Can only be initialized by vault governance

**Parameters:**

| Name            | Type       | Description                                                              |
| --------------- | ---------- | ------------------------------------------------------------------------ |
| `nft_`          | uint256    | NFT of the vault in the VaultRegistry                                    |
| `vaultTokens_`  | address\[] | ERC20 tokens that will be managed by this Vault                          |
| `strategy_`     | address    | The address that will have approvals for subvaultNfts                    |
| `subvaultNfts_` | uint256\[] | The NFTs of the subvaults that will be aggregated by this ERC20RootVault |

**Specs**

* ✅ edge cases: when root vault is not owner of subvault nft reverts with FRB
* ✅ edge cases: when subVault index is 0 (rootVault has itself as subVaul) reverts with DUP
* ✅ edge cases: when subVault index index is 0 reverts with DUP

#### deposit

⛽ 467K (357K - 750K)

```solidity
  function deposit(uint256[] tokenAmounts, uint256 minLpTokens, bytes vaultOptions) external returns (uint256[] actualTokenAmounts)
```

The function of depositing the amount of tokens in exchange

**Parameters:**

| Name           | Type       | Description                            |
| -------------- | ---------- | -------------------------------------- |
| `tokenAmounts` | uint256\[] | Array of amounts of tokens for deposit |
| `minLpTokens`  | uint256    | Minimal value of LP tokens             |
| `vaultOptions` | bytes      | Options of vaults                      |

**Return Values:**

| Name                 | Type       | Description                                  |
| -------------------- | ---------- | -------------------------------------------- |
| `actualTokenAmounts` | uint256\[] | Arrays of actual token amounts after deposit |

**Specs**

* ✅ rsAllowlist returns non zero length of depositorsAllowlist
* ✅ rsAllowlist access control: allowed: any address
* ✅ emits Deposit event
* ✅ checking protocol fees charges fees
* ✅ edge cases: when performance fee is zero do not charge performance fees
* ✅ edge cases: when management fee is zero not charges management fees
* ✅ edge cases: when deposit is disabled reverts with FRB
* ✅ edge cases: when there is no depositor in allow list reverts with FRB
* ✅ edge cases: when there is a private vault in delayedStrategyParams reverts with FRB
* ✅ edge cases: when minLpTokens is greater than lpAmount reverts with LIMU
* ✅ edge cases: when tokenAmounts is less than or equal to FIRST\_DEPOSIT\_LIMIT reverts with LIMU
* ✅ edge cases: when depositCallback Address is set emits deposits callback called
* ✅ edge cases: when lpAmount is zero reverts with VZ
* ✅ edge cases: when sum of lpAmount and sender balance is greater than tokenLimitPerAddress reverts with LIMO
* ✅ edge cases: when sum of lpAmount and totalSupply is greater than tokenLimit reverts with LIMO
* ✅ access control: allowed: any address

#### withdraw

⛽ 499K (364K - 983K)

```solidity
  function withdraw(address to, uint256 lpTokenAmount, uint256[] minTokenAmounts, bytes[] vaultsOptions) external returns (uint256[] actualTokenAmounts)
```

The function of withdrawing the amount of tokens in exchange

**Parameters:**

| Name              | Type       | Description                                              |
| ----------------- | ---------- | -------------------------------------------------------- |
| `to`              | address    | Address to which the withdrawal will be sent             |
| `lpTokenAmount`   | uint256    | LP token amount, that requested for withdraw             |
| `minTokenAmounts` | uint256\[] | Array of minmal remining wtoken amounts after withdrawal |
| `vaultsOptions`   | bytes\[]   | Options of vaults                                        |

**Return Values:**

| Name                 | Type       | Description                                     |
| -------------------- | ---------- | ----------------------------------------------- |
| `actualTokenAmounts` | uint256\[] | Arrays of actual token amounts after withdrawal |

**Specs**

* ✅ emits Withdraw event
* ✅ edge cases: when total supply is 0 reverts with VZ
* ✅ edge cases: when length of vaultsOptions and length of \_subvaultNfts are different reverts with INVL
* ✅ edge cases: when withdrawn is larger than protocol governance withdraw limit for vault token reverts with LIMO
* ✅ edge cases: When address of lpCallback is not null emits withdrawCallback
* ✅ edge cases: When address of lpCallback is not null and lpCallback throws empty error emits WithdrawCallbackLog
* ✅ edge cases: When address of lpCallback is not null and lpCallback throws non empty error emits WithdrawCallbackLog
* ✅ access control: allowed: any address

### Events

#### ManagementFeesCharged

```solidity
  event ManagementFeesCharged(address treasury, uint256 feeRate, uint256 amount)
```

Emitted when management fees are charged

**Parameters:**

| Name       | Type    | Description                                  |
| ---------- | ------- | -------------------------------------------- |
| `treasury` | address | Treasury receiver of the fee                 |
| `feeRate`  | uint256 | Fee percent applied denominated in 10 \*\* 9 |
| `amount`   | uint256 | Amount of lp token minted                    |

#### ProtocolFeesCharged

```solidity
  event ProtocolFeesCharged(address treasury, uint256 feeRate, uint256 amount)
```

Emitted when protocol fees are charged

**Parameters:**

| Name       | Type    | Description                                  |
| ---------- | ------- | -------------------------------------------- |
| `treasury` | address | Treasury receiver of the fee                 |
| `feeRate`  | uint256 | Fee percent applied denominated in 10 \*\* 9 |
| `amount`   | uint256 | Amount of lp token minted                    |

#### PerformanceFeesCharged

```solidity
  event PerformanceFeesCharged(address treasury, uint256 feeRate, uint256 amount)
```

Emitted when performance fees are charged

**Parameters:**

| Name       | Type    | Description                                  |
| ---------- | ------- | -------------------------------------------- |
| `treasury` | address | Treasury receiver of the fee                 |
| `feeRate`  | uint256 | Fee percent applied denominated in 10 \*\* 9 |
| `amount`   | uint256 | Amount of lp token minted                    |

#### Deposit

```solidity
  event Deposit(address from, address[] tokens, uint256[] actualTokenAmounts, uint256 lpTokenMinted)
```

Emitted when liquidity is deposited

**Parameters:**

| Name                 | Type       | Description                                  |
| -------------------- | ---------- | -------------------------------------------- |
| `from`               | address    | The source address for the liquidity         |
| `tokens`             | address\[] | ERC20 tokens deposited                       |
| `actualTokenAmounts` | uint256\[] | Token amounts deposited                      |
| `lpTokenMinted`      | uint256    | LP tokens received by the liquidity provider |

#### Withdraw

```solidity
  event Withdraw(address from, address[] tokens, uint256[] actualTokenAmounts, uint256 lpTokenBurned)
```

Emitted when liquidity is withdrawn

**Parameters:**

| Name                 | Type       | Description                                  |
| -------------------- | ---------- | -------------------------------------------- |
| `from`               | address    | The source address for the liquidity         |
| `tokens`             | address\[] | ERC20 tokens withdrawn                       |
| `actualTokenAmounts` | uint256\[] | Token amounts withdrawn                      |
| `lpTokenBurned`      | uint256    | LP tokens burned from the liquidity provider |

#### DepositCallbackLog

```solidity
  event DepositCallbackLog(string reason)
```

Emitted when callback in deposit failed

**Parameters:**

| Name     | Type   | Description  |
| -------- | ------ | ------------ |
| `reason` | string | Error reason |

#### WithdrawCallbackLog

```solidity
  event WithdrawCallbackLog(string reason)
```

Emitted when callback in withdraw failed

**Parameters:**

| Name     | Type   | Description  |
| -------- | ------ | ------------ |
| `reason` | string | Error reason |

## ERC20RootVaultGovernance

*Inherits from* [*VaultGovernance*](#vaultgovernance)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 4.53M

Governance that manages all Lp Issuers params and can deploy a new LpIssuer Vault.

### Functions

#### constructor

```solidity
  function constructor(struct IVaultGovernance.InternalParams internalParams_, struct IERC20RootVaultGovernance.DelayedProtocolParams delayedProtocolParams_, contract IERC20RootVaultHelper helper_) public
```

Creates a new contract.

**Parameters:**

| Name                     | Type                                                   | Description             |
| ------------------------ | ------------------------------------------------------ | ----------------------- |
| `internalParams_`        | struct IVaultGovernance.InternalParams                 | Initial Internal Params |
| `delayedProtocolParams_` | struct IERC20RootVaultGovernance.DelayedProtocolParams | Initial Protocol Params |

**Specs**

* ✅ deploys a new contract
* ✅ initializes internalParams

*Edge cases*

* ✅ when protocolGovernance address is 0 reverts
* ✅ when vaultRegistry address is 0 reverts

#### delayedProtocolParams

```solidity
  function delayedProtocolParams() public returns (struct IERC20RootVaultGovernance.DelayedProtocolParams)
```

Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Specs**

* ✅ returns current DelayedProtocolParams

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ staging DelayedProtocolParams doesn't change delayedProtocolParams

*Edge cases*

* ✅ when no params were committed returns non-zero params initialized in constructor

#### stagedDelayedProtocolParams

```solidity
  function stagedDelayedProtocolParams() external returns (struct IERC20RootVaultGovernance.DelayedProtocolParams)
```

Delayed Protocol Params staged for commit after delay.

**Specs**

* ✅ returns DelayedProtocolParams staged for commit

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ always equals to params that were just staged

*Edge cases*

* ✅ when no params are staged for commit returns zero struct
* ✅ when params were just committed returns zero struct

#### delayedProtocolPerVaultParams

```solidity
  function delayedProtocolPerVaultParams(uint256 nft) external returns (struct IERC20RootVaultGovernance.DelayedProtocolPerVaultParams)
```

Delayed Protocol Per Vault Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

**Specs**

* ✅ returns current DelayedProtocolPerVaultParams

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ staging DelayedProtocolPerVaultParams doesn't change delayedProtocolPerVaultParams

*Edge cases*

* ✅ when no params were committed returns zero params

#### stagedDelayedProtocolPerVaultParams

```solidity
  function stagedDelayedProtocolPerVaultParams(uint256 nft) external returns (struct IERC20RootVaultGovernance.DelayedProtocolPerVaultParams)
```

Delayed Protocol Per Vault Params staged for commit after delay.

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

**Specs**

* ✅ returns DelayedProtocolPerVaultParams staged for commit

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ always equals to params that were just staged

*Edge cases*

* ✅ when no params are staged for commit returns zero struct
* ✅ when params were just committed returns zero struct

#### stagedDelayedStrategyParams

```solidity
  function stagedDelayedStrategyParams(uint256 nft) external returns (struct IERC20RootVaultGovernance.DelayedStrategyParams)
```

Delayed Strategy Params staged for commit after delay.

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

**Specs**

* ✅ returns DelayedStrategyParams staged for commit

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ always equals to params that were just staged

*Edge cases*

* ✅ when no params are staged for commit returns zero struct
* ✅ when params were just committed returns zero struct

#### operatorParams

```solidity
  function operatorParams() external returns (struct IERC20RootVaultGovernance.OperatorParams)
```

Operator Params.

**Specs**

* ✅ returns operatorParams

*Access control*

* ✅ allowed: any address

*Edge cases*

* ✅ when operatorParams have not been set returns zero params

#### delayedStrategyParams

```solidity
  function delayedStrategyParams(uint256 nft) external returns (struct IERC20RootVaultGovernance.DelayedStrategyParams)
```

Delayed Strategy Params

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

**Specs**

* ✅ returns current DelayedStrategyParams

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ staging DelayedStrategyParams doesn't change delayedStrategyParams

*Edge cases*

* ✅ when no params were committed returns zero params

#### strategyParams

```solidity
  function strategyParams(uint256 nft) external returns (struct IERC20RootVaultGovernance.StrategyParams)
```

Strategy Params.

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

**Specs**

* ✅ returns true if this contract supports 0x6a2c3330 interface
* ✅ access control: allowed: any address

#### stageDelayedStrategyParams

⛽ 160K (67K - 244K)

```solidity
  function stageDelayedStrategyParams(uint256 nft, struct IERC20RootVaultGovernance.DelayedStrategyParams params) external
```

Stage Delayed Strategy Params, i.e. Params that could be changed by Strategy or Protocol Governance with Protocol Governance delay.

**Parameters:**

| Name     | Type                                                   | Description                    |
| -------- | ------------------------------------------------------ | ------------------------------ |
| `nft`    | uint256                                                | VaultRegistry NFT of the vault |
| `params` | struct IERC20RootVaultGovernance.DelayedStrategyParams | New params                     |

**Specs**

* ✅ stages DelayedStrategyParams for commit
* ✅ sets zero delay for commit when #commitDelayedStrategyParams was called 0 times (init)
* ✅ sets governance delay for commit after #commitDelayedStrategyParams was called at least once
* ✅ emits StageDelayedStrategyParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ allowed: Vault NFT Approved (aka strategy)
* ✅ allowed: Vault NFT Owner (aka liquidity provider)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address

*Edge cases*

* ✅ when managementFee is exceeds MAX\_MANAGEMENT\_FEE reverts with LIMO
* ✅ when performnaceFee is exceeds MAX\_PERFORMANCE\_FEE reverts with LIMO
* ✅ when called twice succeeds with the last value
* ✅ when called with zero params succeeds with zero params

#### commitDelayedStrategyParams

⛽ 118K (75K - 195K)

```solidity
  function commitDelayedStrategyParams(uint256 nft) external
```

Commit Delayed Strategy Params, i.e. Params that could be changed by Strategy or Protocol Governance with Protocol Governance delay.

📕 Can only be called after delayedStrategyParamsTimestamp

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

**Specs**

* ✅ commits staged DelayedStrategyParams
* ✅ resets delay for commit
* ✅ emits CommitDelayedStrategyParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ allowed: Vault NFT Owner (aka liquidity provider)
* ✅ allowed: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address
* ✅ reverts if called before the delay has elapsed (after commit was called initally)
* ✅ succeeds if called after the delay has elapsed

*Edge cases*

* ✅ when called twice reverts
* ✅ when nothing is staged reverts
* ✅ when delay has not elapsed (after initial commit call) reverts

#### stageDelayedProtocolPerVaultParams

⛽ 108K (54K - 108K)

```solidity
  function stageDelayedProtocolPerVaultParams(uint256 nft, struct IERC20RootVaultGovernance.DelayedProtocolPerVaultParams params) external
```

Stage Delayed Protocol Per Vault Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Parameters:**

| Name     | Type                                                           | Description                    |
| -------- | -------------------------------------------------------------- | ------------------------------ |
| `nft`    | uint256                                                        | VaultRegistry NFT of the vault |
| `params` | struct IERC20RootVaultGovernance.DelayedProtocolPerVaultParams | New params                     |

**Specs**

* ✅ stages DelayedProtocolPerVaultParams for commit
* ✅ sets delay for commit
* ✅ emits StageDelayedProtocolPerVaultParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ denied: Vault NFT Owner (aka liquidity provider)
* ✅ denied: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address

*Edge cases*

* ✅ when called twice succeeds with the last value
* ✅ when called with zero params succeeds with zero params
* ✅ when protocol fee is greater than MAX\_PROTOCOL\_FEE reverts

#### commitDelayedProtocolPerVaultParams

⛽ 80K (44K - 80K)

```solidity
  function commitDelayedProtocolPerVaultParams(uint256 nft) external
```

Commit Delayed Protocol Per Vault Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

📕 Can only be called after delayedProtocolPerVaultParamsTimestamp

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

**Specs**

* ✅ commits staged DelayedProtocolPerVaultParams
* ✅ resets delay for commit
* ✅ emits CommitDelayedProtocolPerVaultParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ denied: Vault NFT Owner (aka liquidity provider)
* ✅ denied: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address
* ✅ reverts if called before the delay has elapsed only if params have already been commited
* ✅ succeeds if called after the delay has elapsed

*Edge cases*

* ✅ when called twice reverts
* ✅ when nothing is staged reverts
* ✅ when delay has not elapsed and params have not been commited reverts
* ✅ when params have already been set and delay has not elapsed reverts

#### setStrategyParams

⛽ 113K (37K - 115K)

```solidity
  function setStrategyParams(uint256 nft, struct IERC20RootVaultGovernance.StrategyParams params) external
```

Set Strategy params, i.e. Params that could be changed by Strategy or Protocol Governance immediately.

**Parameters:**

| Name     | Type                                            | Description      |
| -------- | ----------------------------------------------- | ---------------- |
| `nft`    | uint256                                         | Nft of the vault |
| `params` | struct IERC20RootVaultGovernance.StrategyParams | New params       |

#### setOperatorParams

⛽ 51K (35K - 77K)

```solidity
  function setOperatorParams(struct IERC20RootVaultGovernance.OperatorParams params) external
```

Set Operator params, i.e. Params that could be changed by Operator or Protocol Governance immediately.

**Parameters:**

| Name     | Type                                            | Description |
| -------- | ----------------------------------------------- | ----------- |
| `params` | struct IERC20RootVaultGovernance.OperatorParams | New params  |

**Specs**

* ✅ sets new operatorParams
* ✅ access constrol allowed: ProtocolGovernance admin or Operator
* ✅ access constrol denied: any other address

*Properties*

* ✅ setting new oprator params overwrites old params immediately

#### stageDelayedProtocolParams

⛽ 88K (52K - 129K)

```solidity
  function stageDelayedProtocolParams(struct IERC20RootVaultGovernance.DelayedProtocolParams params) external
```

Stage Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

📕 Can only be called after delayedProtocolParamsTimestamp.

**Parameters:**

| Name     | Type                                                   | Description |
| -------- | ------------------------------------------------------ | ----------- |
| `params` | struct IERC20RootVaultGovernance.DelayedProtocolParams | New params  |

**Specs**

* ✅ stages DelayedProtocolParams for commit
* ✅ sets delay for commit
* ✅ emits StageDelayedProtocolParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ denied: Vault NFT Owner (aka liquidity provider)
* ✅ denied: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address

*Edge cases*

* ✅ when called twice succeeds with the last value
* ✅ when called with zero params reverts with zero params

#### commitDelayedProtocolParams

⛽ 50K (49K - 54K)

```solidity
  function commitDelayedProtocolParams() external
```

Commit Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Specs**

* ✅ commits staged DelayedProtocolParams
* ✅ resets delay for commit
* ✅ emits CommitDelayedProtocolParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ denied: Vault NFT Owner (aka liquidity provider)
* ✅ denied: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address
* ✅ reverts if called before the delay has elapsed
* ✅ succeeds if called after the delay has elapsed

*Edge cases*

* ✅ when called twice reverts
* ✅ when nothing is staged reverts
* ✅ when delay has not elapsed reverts

#### createVault

⛽ 915K (794K - 1.32M)

```solidity
  function createVault(address[] vaultTokens_, address strategy_, uint256[] subvaultNfts_, address owner_) external returns (contract IERC20RootVault vault, uint256 nft)
```

Deploys a new vault.

**Parameters:**

| Name            | Type       | Description                                                              |
| --------------- | ---------- | ------------------------------------------------------------------------ |
| `vaultTokens_`  | address\[] | ERC20 tokens that will be managed by this Vault                          |
| `strategy_`     | address    | The address that will have approvals for subvaultNfts                    |
| `subvaultNfts_` | uint256\[] | The NFTs of the subvaults that will be aggregated by this ERC20RootVault |
| `owner_`        | address    | Owner of the vault NFT                                                   |

**Specs**

* ✅ deploys a new vault
* ✅ registers vault with vault registry and issues nft
* ✅ the nft is owned by the owner from #createVault arguments
* ✅ vault is initialized with nft

*Access control*

* ✅ when permissionless allowed: any address
* ✅ when not permissionless allowed: protocol governance admin
* ✅ when not permissionless denied: any address

### Structs

```solidity
struct DelayedStrategyParams {
    address strategyTreasury;
    address strategyPerformanceTreasury;
    bool privateVault;
    uint256 managementFee;
    uint256 performanceFee;
    address depositCallbackAddress;
    address withdrawCallbackAddress;
}
```

```solidity
struct DelayedProtocolParams {
    uint256 managementFeeChargeDelay;
    IOracle oracle;
}
```

```solidity
struct StrategyParams {
    uint256 tokenLimitPerAddress;
    uint256 tokenLimit;
}
```

```solidity
struct DelayedProtocolPerVaultParams {
    uint256 protocolFee;
}
```

```solidity
struct OperatorParams {
    bool disableDeposit;
}
```

```solidity
struct InternalParams {
    IProtocolGovernance protocolGovernance;
    IVaultRegistry registry;
    IVault singleton;
}
```

### Events

#### StageDelayedProtocolPerVaultParams

```solidity
  event StageDelayedProtocolPerVaultParams(address origin, address sender, uint256 nft, struct IERC20RootVaultGovernance.DelayedProtocolPerVaultParams params, uint256 when)
```

Emitted when new DelayedProtocolPerVaultParams are staged for commit

**Parameters:**

| Name     | Type                                                           | Description                            |
| -------- | -------------------------------------------------------------- | -------------------------------------- |
| `origin` | address                                                        | Origin of the transaction (tx.origin)  |
| `sender` | address                                                        | Sender of the call (msg.sender)        |
| `nft`    | uint256                                                        | VaultRegistry NFT of the vault         |
| `params` | struct IERC20RootVaultGovernance.DelayedProtocolPerVaultParams | New params that were staged for commit |
| `when`   | uint256                                                        | When the params could be committed     |

#### CommitDelayedProtocolPerVaultParams

```solidity
  event CommitDelayedProtocolPerVaultParams(address origin, address sender, uint256 nft, struct IERC20RootVaultGovernance.DelayedProtocolPerVaultParams params)
```

Emitted when new DelayedProtocolPerVaultParams are committed

**Parameters:**

| Name     | Type                                                           | Description                           |
| -------- | -------------------------------------------------------------- | ------------------------------------- |
| `origin` | address                                                        | Origin of the transaction (tx.origin) |
| `sender` | address                                                        | Sender of the call (msg.sender)       |
| `nft`    | uint256                                                        | VaultRegistry NFT of the vault        |
| `params` | struct IERC20RootVaultGovernance.DelayedProtocolPerVaultParams | New params that are committed         |

#### StageDelayedStrategyParams

```solidity
  event StageDelayedStrategyParams(address origin, address sender, uint256 nft, struct IERC20RootVaultGovernance.DelayedStrategyParams params, uint256 when)
```

Emitted when new DelayedStrategyParams are staged for commit

**Parameters:**

| Name     | Type                                                   | Description                            |
| -------- | ------------------------------------------------------ | -------------------------------------- |
| `origin` | address                                                | Origin of the transaction (tx.origin)  |
| `sender` | address                                                | Sender of the call (msg.sender)        |
| `nft`    | uint256                                                | VaultRegistry NFT of the vault         |
| `params` | struct IERC20RootVaultGovernance.DelayedStrategyParams | New params that were staged for commit |
| `when`   | uint256                                                | When the params could be committed     |

#### CommitDelayedStrategyParams

```solidity
  event CommitDelayedStrategyParams(address origin, address sender, uint256 nft, struct IERC20RootVaultGovernance.DelayedStrategyParams params)
```

Emitted when new DelayedStrategyParams are committed

**Parameters:**

| Name     | Type                                                   | Description                           |
| -------- | ------------------------------------------------------ | ------------------------------------- |
| `origin` | address                                                | Origin of the transaction (tx.origin) |
| `sender` | address                                                | Sender of the call (msg.sender)       |
| `nft`    | uint256                                                | VaultRegistry NFT of the vault        |
| `params` | struct IERC20RootVaultGovernance.DelayedStrategyParams | New params that are committed         |

#### SetStrategyParams

```solidity
  event SetStrategyParams(address origin, address sender, uint256 nft, struct IERC20RootVaultGovernance.StrategyParams params)
```

Emitted when new StrategyParams are set.

**Parameters:**

| Name     | Type                                            | Description                           |
| -------- | ----------------------------------------------- | ------------------------------------- |
| `origin` | address                                         | Origin of the transaction (tx.origin) |
| `sender` | address                                         | Sender of the call (msg.sender)       |
| `nft`    | uint256                                         | VaultRegistry NFT of the vault        |
| `params` | struct IERC20RootVaultGovernance.StrategyParams | New params that are set               |

#### SetOperatorParams

```solidity
  event SetOperatorParams(address origin, address sender, struct IERC20RootVaultGovernance.OperatorParams params)
```

Emitted when new OperatorParams are set.

**Parameters:**

| Name     | Type                                            | Description                           |
| -------- | ----------------------------------------------- | ------------------------------------- |
| `origin` | address                                         | Origin of the transaction (tx.origin) |
| `sender` | address                                         | Sender of the call (msg.sender)       |
| `params` | struct IERC20RootVaultGovernance.OperatorParams | New params that are set               |

#### StageDelayedProtocolParams

```solidity
  event StageDelayedProtocolParams(address origin, address sender, struct IERC20RootVaultGovernance.DelayedProtocolParams params, uint256 when)
```

Emitted when new DelayedProtocolParams are staged for commit

**Parameters:**

| Name     | Type                                                   | Description                            |
| -------- | ------------------------------------------------------ | -------------------------------------- |
| `origin` | address                                                | Origin of the transaction (tx.origin)  |
| `sender` | address                                                | Sender of the call (msg.sender)        |
| `params` | struct IERC20RootVaultGovernance.DelayedProtocolParams | New params that were staged for commit |
| `when`   | uint256                                                | When the params could be committed     |

#### CommitDelayedProtocolParams

```solidity
  event CommitDelayedProtocolParams(address origin, address sender, struct IERC20RootVaultGovernance.DelayedProtocolParams params)
```

Emitted when new DelayedProtocolParams are committed

**Parameters:**

| Name     | Type                                                   | Description                           |
| -------- | ------------------------------------------------------ | ------------------------------------- |
| `origin` | address                                                | Origin of the transaction (tx.origin) |
| `sender` | address                                                | Sender of the call (msg.sender)       |
| `params` | struct IERC20RootVaultGovernance.DelayedProtocolParams | New params that are committed         |

## ERC20Vault

*Inherits from* [*Vault*](#vault)*,* [*ERC165*](#erc165)*,* [*ReentrancyGuard*](#reentrancyguard)

⛽ 4.41M

Vault that stores ERC20 tokens.

#### tvl

```solidity
  function tvl() public returns (uint256[] minTokenAmounts, uint256[] maxTokenAmounts)
```

Total value locked for this contract.

📕 Generally it is the underlying token value of this contract in some other DeFi protocol. For example, for USDC Yearn Vault this would be total USDC balance that could be withdrawn for Yearn to this contract. The tvl itself is estimated in some range. Sometimes the range is exact, sometimes it's not

**Return Values:**

| Name              | Type       | Description                                                                                                   |
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| `minTokenAmounts` | uint256\[] | Lower bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |
| `maxTokenAmounts` | uint256\[] | Upper bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |

**Specs**

* ✅ returns total value locked
* ✅ edge cases: when there are no initial funds returns zeroes

#### initialize

```solidity
  function initialize(uint256 nft_, address[] vaultTokens_) external
```

Initialized a new contract.

📕 Can only be initialized by vault governance

**Parameters:**

| Name           | Type       | Description                                     |
| -------------- | ---------- | ----------------------------------------------- |
| `nft_`         | uint256    | NFT of the vault in the VaultRegistry           |
| `vaultTokens_` | address\[] | ERC20 tokens that will be managed by this Vault |

**Specs**

* ✅ emits Initialized event
* ✅ initializes contract successfully
* ✅ edge cases: when vault's nft is not 0 reverts with INIT
* ✅ edge cases: not initialized when vault's nft is 0 returns false
* ✅ edge cases: when tokens are not sorted reverts with INVA
* ✅ edge cases: when tokens are not unique reverts with INVA
* ✅ edge cases: when setting zero nft reverts with VZ
* ✅ edge cases: when setting empty tokens array reverts with INV
* ✅ edge cases: when token has no permission to become a vault token reverts with FRB

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true if this contract supports 0x7a63aa3a interface
* ✅ access control: allowed: any address
* ✅ edge cases: when contract does not support the given interface returns false

## ERC20VaultGovernance

*Inherits from* [*VaultGovernance*](#vaultgovernance)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 1.59M

Governance that manages all ERC20 Vaults params and can deploy a new ERC20 Vault.

### Functions

#### constructor

```solidity
  function constructor(struct IVaultGovernance.InternalParams internalParams_) public
```

Creates a new contract.

**Parameters:**

| Name              | Type                                   | Description             |
| ----------------- | -------------------------------------- | ----------------------- |
| `internalParams_` | struct IVaultGovernance.InternalParams | Initial Internal Params |

**Specs**

* ✅ deploys a new contract
* ✅ initializes internalParams

*Edge cases*

* ✅ when protocolGovernance address is 0 reverts
* ✅ when vaultRegistry address is 0 reverts

#### createVault

⛽ 475K (463K - 648K)

```solidity
  function createVault(address[] vaultTokens_, address owner_) external returns (contract IERC20Vault vault, uint256 nft)
```

Deploys a new vault.

**Parameters:**

| Name           | Type       | Description                                     |
| -------------- | ---------- | ----------------------------------------------- |
| `vaultTokens_` | address\[] | ERC20 tokens that will be managed by this Vault |
| `owner_`       | address    | Owner of the vault NFT                          |

**Specs**

* ✅ deploys a new vault
* ✅ registers vault with vault registry and issues nft
* ✅ the nft is owned by the owner from #createVault arguments
* ✅ vault is initialized with nft

*Access control*

* ✅ when permissionless allowed: any address
* ✅ when not permissionless allowed: protocol governance admin
* ✅ when not permissionless denied: any address

### Structs

```solidity
struct InternalParams {
    IProtocolGovernance protocolGovernance;
    IVaultRegistry registry;
    IVault singleton;
}
```

## GearboxRootVault

*Inherits from* [*AggregateVault*](#aggregatevault)*,* [*Vault*](#vault)*,* [*ERC165*](#erc165)*,* [*ReentrancyGuard*](#reentrancyguard)*,* [*ERC20Token*](#erc20token)

Contract that mints and burns LP tokens in exchange for ERC20 liquidity.

### Functions

#### depositorsAllowlist

```solidity
  function depositorsAllowlist() external returns (address[])
```

List of addresses of depositors from which interaction with private vaults is allowed

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

#### addDepositorsToAllowlist

```solidity
  function addDepositorsToAllowlist(address[] depositors) external
```

Add new depositors in the depositorsAllowlist

📕 The action can be done only by user with admins, owners or by approved rights

**Parameters:**

| Name         | Type       | Description             |
| ------------ | ---------- | ----------------------- |
| `depositors` | address\[] | Array of new depositors |

#### removeDepositorsFromAllowlist

```solidity
  function removeDepositorsFromAllowlist(address[] depositors) external
```

Remove depositors from the depositorsAllowlist

📕 The action can be done only by user with admins, owners or by approved rights

**Parameters:**

| Name         | Type       | Description                    |
| ------------ | ---------- | ------------------------------ |
| `depositors` | address\[] | Array of depositors for remove |

#### initialize

```solidity
  function initialize(uint256 nft_, address[] vaultTokens_, address strategy_, uint256[] subvaultNfts_, address) external
```

Initialized a new contract.

📕 Can only be initialized by vault governance

**Parameters:**

| Name            | Type       | Description                                                              |
| --------------- | ---------- | ------------------------------------------------------------------------ |
| `nft_`          | uint256    | NFT of the vault in the VaultRegistry                                    |
| `vaultTokens_`  | address\[] | ERC20 tokens that will be managed by this Vault                          |
| `strategy_`     | address    | The address that will have approvals for subvaultNfts                    |
| `subvaultNfts_` | uint256\[] | The NFTs of the subvaults that will be aggregated by this ERC20RootVault |

#### deposit

```solidity
  function deposit(uint256[] tokenAmounts, uint256 minLpTokens, bytes vaultOptions) external returns (uint256[] actualTokenAmounts)
```

The function of depositing the amount of tokens in exchange

**Parameters:**

| Name           | Type       | Description                            |
| -------------- | ---------- | -------------------------------------- |
| `tokenAmounts` | uint256\[] | Array of amounts of tokens for deposit |
| `minLpTokens`  | uint256    | Minimal value of LP tokens             |
| `vaultOptions` | bytes      | Options of vaults                      |

**Return Values:**

| Name                 | Type       | Description                                  |
| -------------------- | ---------- | -------------------------------------------- |
| `actualTokenAmounts` | uint256\[] | Arrays of actual token amounts after deposit |

#### registerWithdrawal

```solidity
  function registerWithdrawal(uint256 lpTokenAmount) external returns (uint256 amountRegistered)
```

The function of registering withdrawal of lp tokens amount

**Parameters:**

| Name            | Type    | Description                         |
| --------------- | ------- | ----------------------------------- |
| `lpTokenAmount` | uint256 | Amount the sender wants to withdraw |

**Return Values:**

| Name               | Type    | Description                          |
| ------------------ | ------- | ------------------------------------ |
| `amountRegistered` | uint256 | Amount which was actually registered |

#### cancelWithdrawal

```solidity
  function cancelWithdrawal(uint256 lpTokenAmount) external returns (uint256 amountRemained)
```

The function of cancelling withdrawal of lp tokens amount

**Parameters:**

| Name            | Type    | Description                       |
| --------------- | ------- | --------------------------------- |
| `lpTokenAmount` | uint256 | Amount the sender wants to cancel |

**Return Values:**

| Name             | Type    | Description                                     |
| ---------------- | ------- | ----------------------------------------------- |
| `amountRemained` | uint256 | Amount for which the withdrawal request remains |

#### invokeExecution

```solidity
  function invokeExecution() public
```

The function of invoking the execution of withdrawal orders and transfers corresponding funds to ERC20 vault

#### withdraw

```solidity
  function withdraw(address to, bytes[] vaultsOptions) external returns (uint256[] actualTokenAmounts)
```

The function of withdrawing the amount of tokens in exchange

**Parameters:**

| Name            | Type     | Description                                  |
| --------------- | -------- | -------------------------------------------- |
| `to`            | address  | Address to which the withdrawal will be sent |
| `vaultsOptions` | bytes\[] | Options of vaults                            |

**Return Values:**

| Name                 | Type       | Description                                     |
| -------------------- | ---------- | ----------------------------------------------- |
| `actualTokenAmounts` | uint256\[] | Arrays of actual token amounts after withdrawal |

#### shutdown

```solidity
  function shutdown() external
```

The function of invoking the emergency execution of withdrawal orders, transfers corresponding funds to ERC20 vault and stops deposits

#### reopen

```solidity
  function reopen() external
```

The function of opening deposits back in case of a previous shutdown

### Events

#### ManagementFeesCharged

```solidity
  event ManagementFeesCharged(address treasury, uint256 feeRate, uint256 amount)
```

Emitted when management fees are charged

**Parameters:**

| Name       | Type    | Description                                  |
| ---------- | ------- | -------------------------------------------- |
| `treasury` | address | Treasury receiver of the fee                 |
| `feeRate`  | uint256 | Fee percent applied denominated in 10 \*\* 9 |
| `amount`   | uint256 | Amount of lp token minted                    |

#### WithdrawalRegistered

```solidity
  event WithdrawalRegistered(address sender, uint256 lpAmountRegistered)
```

Emitted when a witdrawal request registered

**Parameters:**

| Name                 | Type    | Description                                       |
| -------------------- | ------- | ------------------------------------------------- |
| `sender`             | address | Sender of the call (msg.sender)                   |
| `lpAmountRegistered` | uint256 | Amount of lp tokens registered for the withdrawal |

#### WithdrawalCancelled

```solidity
  event WithdrawalCancelled(address sender, uint256 lpAmountCancelled)
```

Emitted when some piece of the witdrawal request cancelled

**Parameters:**

| Name                | Type    | Description                                               |
| ------------------- | ------- | --------------------------------------------------------- |
| `sender`            | address | Sender of the call (msg.sender)                           |
| `lpAmountCancelled` | uint256 | Amount of lp tokens for which the withdrawal is cancelled |

#### ExecutionInvoked

```solidity
  event ExecutionInvoked(address sender, uint256 amountWithdrawnToERC20)
```

Emitted when the withdrawal orderd execution completed

**Parameters:**

| Name                     | Type    | Description                                                      |
| ------------------------ | ------- | ---------------------------------------------------------------- |
| `sender`                 | address | Sender of the call (msg.sender)                                  |
| `amountWithdrawnToERC20` | uint256 | Amount of vault tokens withdrawn from Gearbox to the ERC20 vault |

#### ProtocolFeesCharged

```solidity
  event ProtocolFeesCharged(address treasury, uint256 feeRate, uint256 amount)
```

Emitted when protocol fees are charged

**Parameters:**

| Name       | Type    | Description                                  |
| ---------- | ------- | -------------------------------------------- |
| `treasury` | address | Treasury receiver of the fee                 |
| `feeRate`  | uint256 | Fee percent applied denominated in 10 \*\* 9 |
| `amount`   | uint256 | Amount of lp token minted                    |

#### PerformanceFeesCharged

```solidity
  event PerformanceFeesCharged(address treasury, uint256 feeRate, uint256 amount)
```

Emitted when performance fees are charged

**Parameters:**

| Name       | Type    | Description                                  |
| ---------- | ------- | -------------------------------------------- |
| `treasury` | address | Treasury receiver of the fee                 |
| `feeRate`  | uint256 | Fee percent applied denominated in 10 \*\* 9 |
| `amount`   | uint256 | Amount of lp token minted                    |

#### Deposit

```solidity
  event Deposit(address from, address[] tokens, uint256[] actualTokenAmounts, uint256 lpTokenMinted)
```

Emitted when liquidity is deposited

**Parameters:**

| Name                 | Type       | Description                                  |
| -------------------- | ---------- | -------------------------------------------- |
| `from`               | address    | The source address for the liquidity         |
| `tokens`             | address\[] | ERC20 tokens deposited                       |
| `actualTokenAmounts` | uint256\[] | Token amounts deposited                      |
| `lpTokenMinted`      | uint256    | LP tokens received by the liquidity provider |

#### Withdraw

```solidity
  event Withdraw(address from, uint256[] actualTokenAmounts, uint256 lpTokenBurned)
```

Emitted when liquidity is withdrawn

**Parameters:**

| Name                 | Type       | Description                                  |
| -------------------- | ---------- | -------------------------------------------- |
| `from`               | address    | The source address for the liquidity         |
| `actualTokenAmounts` | uint256\[] | Token amounts withdrawn                      |
| `lpTokenBurned`      | uint256    | LP tokens burned from the liquidity provider |

#### DepositCallbackLog

```solidity
  event DepositCallbackLog(string reason)
```

Emitted when callback in deposit failed

**Parameters:**

| Name     | Type   | Description  |
| -------- | ------ | ------------ |
| `reason` | string | Error reason |

#### WithdrawCallbackLog

```solidity
  event WithdrawCallbackLog(string reason)
```

Emitted when callback in withdraw failed

**Parameters:**

| Name     | Type   | Description  |
| -------- | ------ | ------------ |
| `reason` | string | Error reason |

## GearboxVault

*Inherits from* [*Vault*](#vault)*,* [*ERC165*](#erc165)*,* [*ReentrancyGuard*](#reentrancyguard)

### Functions

#### tvl

```solidity
  function tvl() public returns (uint256[] minTokenAmounts, uint256[] maxTokenAmounts)
```

Total value locked for this contract.

📕 Generally it is the underlying token value of this contract in some other DeFi protocol. For example, for USDC Yearn Vault this would be total USDC balance that could be withdrawn for Yearn to this contract. The tvl itself is estimated in some range. Sometimes the range is exact, sometimes it's not

**Return Values:**

| Name              | Type       | Description                                                                                                   |
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| `minTokenAmounts` | uint256\[] | Lower bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |
| `maxTokenAmounts` | uint256\[] | Upper bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

#### getCreditAccount

```solidity
  function getCreditAccount() public returns (address)
```

Returns an address of the credit account connected to the address of the vault

#### getAllAssetsOnCreditAccountValue

```solidity
  function getAllAssetsOnCreditAccountValue() external returns (uint256 currentAllAssetsValue)
```

Returns value of all assets located on the vault, including taken with leverage (nominated in primary tokens)

#### getClaimableRewardsValue

```solidity
  function getClaimableRewardsValue() external returns (uint256)
```

Returns value of rewards (CRV, CVX) we can obtain from Convex (nominated in primary tokens)

#### getMerkleProof

```solidity
  function getMerkleProof() external returns (bytes32[])
```

#### initialize

```solidity
  function initialize(uint256 nft_, address[] vaultTokens_, address helper_) external
```

Initialized a new contract.

📕 Can only be initialized by vault governance

**Parameters:**

| Name           | Type       | Description                                     |
| -------------- | ---------- | ----------------------------------------------- |
| `nft_`         | uint256    | NFT of the vault in the VaultRegistry           |
| `vaultTokens_` | address\[] | ERC20 tokens that will be managed by this Vault |
| `helper_`      | address    | address of helper                               |

#### openCreditAccount

```solidity
  function openCreditAccount() external
```

Opens a new credit account on the address of the vault

#### adjustPosition

```solidity
  function adjustPosition() external
```

Adjust a position (takes more debt or repays some, depending on the past performance) to achieve the required marginalFactorD9

#### setMerkleParameters

```solidity
  function setMerkleParameters(uint256 merkleIndex_, uint256 merkleTotalAmount_, bytes32[] merkleProof_) public
```

Sets merkle tree parameters for claiming Gearbox V2 Degen NFT (can be successfully called only by an admin or a strategist)

**Parameters:**

| Name                 | Type       | Description                                            |
| -------------------- | ---------- | ------------------------------------------------------ |
| `merkleIndex_`       | uint256    | Required index                                         |
| `merkleTotalAmount_` | uint256    | Total amount of NFTs we have in Gearbox Degen Contract |
| `merkleProof_`       | bytes32\[] | Proof in Merkle tree                                   |

#### updateTargetMarginalFactor

```solidity
  function updateTargetMarginalFactor(uint256 marginalFactorD9_) external
```

Updates marginalFactorD9 (can be successfully called only by an admin or a strategist)

**Parameters:**

| Name               | Type    | Description          |
| ------------------ | ------- | -------------------- |
| `marginalFactorD_` | uint256 | New marginalFactorD9 |

#### multicall

```solidity
  function multicall(struct MultiCall[] calls) external
```

A helper function to be able to call Gearbox multicalls from the helper, but on behalf of the vault Can be successfully called only by the helper

#### swap

```solidity
  function swap(contract ISwapRouter router, struct ISwapRouter.ExactOutputParams uniParams, address token, uint256 amount) external
```

A helper function to be able to call Gearbox multicalls from the helper, but on behalf of the vault Can be successfully called only by the helper

#### openCreditAccountInManager

```solidity
  function openCreditAccountInManager(uint256 currentPrimaryTokenAmount, uint16 referralCode) external
```

A helper function to be able to call Gearbox multicalls from the helper, but on behalf of the vault Can be successfully called only by the helper

### Events

#### TargetMarginalFactorUpdated

```solidity
  event TargetMarginalFactorUpdated(address origin, address sender, uint256 newMarginalFactorD9)
```

Emitted when target marginal factor is updated

**Parameters:**

| Name                  | Type    | Description                           |
| --------------------- | ------- | ------------------------------------- |
| `origin`              | address | Origin of the transaction (tx.origin) |
| `sender`              | address | Sender of the call (msg.sender)       |
| `newMarginalFactorD9` | uint256 | New marginal factor                   |

## GearboxVaultGovernance

*Inherits from* [*VaultGovernance*](#vaultgovernance)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

### Functions

#### constructor

```solidity
  function constructor(struct IVaultGovernance.InternalParams internalParams_, struct IGearboxVaultGovernance.DelayedProtocolParams delayedProtocolParams_) public
```

Creates a new contract

#### delayedProtocolParams

```solidity
  function delayedProtocolParams() public returns (struct IGearboxVaultGovernance.DelayedProtocolParams)
```

Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

#### stagedDelayedProtocolParams

```solidity
  function stagedDelayedProtocolParams() external returns (struct IGearboxVaultGovernance.DelayedProtocolParams)
```

Delayed Protocol Params staged for commit after delay.

#### stagedDelayedProtocolPerVaultParams

```solidity
  function stagedDelayedProtocolPerVaultParams(uint256 nft) external returns (struct IGearboxVaultGovernance.DelayedProtocolPerVaultParams)
```

Delayed Protocol Per Vault Params staged for commit after delay.

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

#### strategyParams

```solidity
  function strategyParams(uint256 nft) external returns (struct IGearboxVaultGovernance.StrategyParams)
```

Strategy Params.

#### delayedProtocolPerVaultParams

```solidity
  function delayedProtocolPerVaultParams(uint256 nft) external returns (struct IGearboxVaultGovernance.DelayedProtocolPerVaultParams)
```

Delayed Protocol Per Vault Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

#### stageDelayedProtocolParams

```solidity
  function stageDelayedProtocolParams(struct IGearboxVaultGovernance.DelayedProtocolParams params) external
```

Stage Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

📕 Can only be called after delayedProtocolParamsTimestamp.

**Parameters:**

| Name     | Type                                                 | Description |
| -------- | ---------------------------------------------------- | ----------- |
| `params` | struct IGearboxVaultGovernance.DelayedProtocolParams | New params  |

#### commitDelayedProtocolParams

```solidity
  function commitDelayedProtocolParams() external
```

Commit Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

#### stageDelayedProtocolPerVaultParams

```solidity
  function stageDelayedProtocolPerVaultParams(uint256 nft, struct IGearboxVaultGovernance.DelayedProtocolPerVaultParams params) external
```

#### commitDelayedProtocolPerVaultParams

```solidity
  function commitDelayedProtocolPerVaultParams(uint256 nft) external
```

Commit Delayed Protocol Per Vault Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

📕 Can only be called after delayedProtocolPerVaultParamsTimestamp

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

#### setStrategyParams

```solidity
  function setStrategyParams(uint256 nft, struct IGearboxVaultGovernance.StrategyParams params) external
```

Set Strategy params, i.e. Params that could be changed by Strategy or Protocol Governance immediately.

**Parameters:**

| Name     | Type    | Description |
| -------- | ------- | ----------- |
| `params` | uint256 | New params  |

#### createVault

```solidity
  function createVault(address[] vaultTokens_, address owner_, address helper_) external returns (contract IGearboxVault vault, uint256 nft)
```

Deploys a new vault.

**Parameters:**

| Name           | Type       | Description                                     |
| -------------- | ---------- | ----------------------------------------------- |
| `vaultTokens_` | address\[] | ERC20 tokens that will be managed by this Vault |
| `owner_`       | address    | Owner of the vault NFT                          |
| `helper_`      | address    | Gearbox helper contract address                 |

### Structs

```solidity
struct DelayedProtocolParams {
    uint256 withdrawDelay;
    uint16 referralCode;
    address univ3Adapter;
    address crv;
    address cvx;
    uint256 maxSlippageD9;
    uint256 maxSmallPoolsSlippageD9;
    uint256 maxCurveSlippageD9;
    address uniswapRouter;
}
```

```solidity
struct DelayedProtocolPerVaultParams {
    address primaryToken;
    address curveAdapter;
    address convexAdapter;
    address facade;
    uint256 initialMarginalValueD9;
}
```

```solidity
struct StrategyParams {
    uint24 largePoolFeeUsed;
}
```

```solidity
struct InternalParams {
    IProtocolGovernance protocolGovernance;
    IVaultRegistry registry;
    IVault singleton;
}
```

### Events

#### StageDelayedProtocolPerVaultParams

```solidity
  event StageDelayedProtocolPerVaultParams(address origin, address sender, uint256 nft, struct IGearboxVaultGovernance.DelayedProtocolPerVaultParams params, uint256 when)
```

Emitted when new DelayedProtocolPerVaultParams are staged for commit

**Parameters:**

| Name     | Type                                                         | Description                            |
| -------- | ------------------------------------------------------------ | -------------------------------------- |
| `origin` | address                                                      | Origin of the transaction (tx.origin)  |
| `sender` | address                                                      | Sender of the call (msg.sender)        |
| `nft`    | uint256                                                      | VaultRegistry NFT of the vault         |
| `params` | struct IGearboxVaultGovernance.DelayedProtocolPerVaultParams | New params that were staged for commit |
| `when`   | uint256                                                      | When the params could be committed     |

#### CommitDelayedProtocolPerVaultParams

```solidity
  event CommitDelayedProtocolPerVaultParams(address origin, address sender, uint256 nft, struct IGearboxVaultGovernance.DelayedProtocolPerVaultParams params)
```

Emitted when new DelayedProtocolPerVaultParams are committed

**Parameters:**

| Name     | Type                                                         | Description                           |
| -------- | ------------------------------------------------------------ | ------------------------------------- |
| `origin` | address                                                      | Origin of the transaction (tx.origin) |
| `sender` | address                                                      | Sender of the call (msg.sender)       |
| `nft`    | uint256                                                      | VaultRegistry NFT of the vault        |
| `params` | struct IGearboxVaultGovernance.DelayedProtocolPerVaultParams | New params that are committed         |

#### StageDelayedProtocolParams

```solidity
  event StageDelayedProtocolParams(address origin, address sender, struct IGearboxVaultGovernance.DelayedProtocolParams params, uint256 when)
```

Emitted when new DelayedProtocolParams are staged for commit

**Parameters:**

| Name     | Type                                                 | Description                            |
| -------- | ---------------------------------------------------- | -------------------------------------- |
| `origin` | address                                              | Origin of the transaction (tx.origin)  |
| `sender` | address                                              | Sender of the call (msg.sender)        |
| `params` | struct IGearboxVaultGovernance.DelayedProtocolParams | New params that were staged for commit |
| `when`   | uint256                                              | When the params could be committed     |

#### SetStrategyParams

```solidity
  event SetStrategyParams(address origin, address sender, struct IGearboxVaultGovernance.StrategyParams params)
```

Emitted when new StrategyParams are set.

**Parameters:**

| Name     | Type                                          | Description                           |
| -------- | --------------------------------------------- | ------------------------------------- |
| `origin` | address                                       | Origin of the transaction (tx.origin) |
| `sender` | address                                       | Sender of the call (msg.sender)       |
| `params` | struct IGearboxVaultGovernance.StrategyParams | New params that are set               |

#### CommitDelayedProtocolParams

```solidity
  event CommitDelayedProtocolParams(address origin, address sender, struct IGearboxVaultGovernance.DelayedProtocolParams params)
```

Emitted when new DelayedProtocolParams are committed

**Parameters:**

| Name     | Type                                                 | Description                           |
| -------- | ---------------------------------------------------- | ------------------------------------- |
| `origin` | address                                              | Origin of the transaction (tx.origin) |
| `sender` | address                                              | Sender of the call (msg.sender)       |
| `params` | struct IGearboxVaultGovernance.DelayedProtocolParams | New params that are committed         |

## IntegrationVault

*Inherits from* [*Vault*](#vault)*,* [*ERC165*](#erc165)*,* [*ReentrancyGuard*](#reentrancyguard)

Abstract contract that has logic common for every Vault.

📕 Notes:

#### ERC-721

Each Vault should be registered in VaultRegistry and get corresponding VaultRegistry NFT.

#### Access control

`push` and `pull` methods are only allowed for owner / approved person of the NFT. However, `pull` for approved person also checks that pull destination is another vault of the Vault System.

The semantics is: NFT owner owns all Vault liquidity, Approved person is liquidity manager. ApprovedForAll person cannot do anything except ERC-721 token transfers.

Both NFT owner and approved person can call externalCall method which claims liquidity mining rewards (if any)

`reclaimTokens` for claiming rewards given by an underlying protocol to erc20Vault in order to sell them there

### Functions

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

#### push

```solidity
  function push(address[] tokens, uint256[] tokenAmounts, bytes options) public returns (uint256[] actualTokenAmounts)
```

Pushes tokens on the vault balance to the underlying protocol. For example, for Yearn this operation will take USDC from the contract balance and convert it to yUSDC.

📕 Tokens **must** be a subset of Vault Tokens. However, the convention is that if tokenAmount == 0 it is the same as token is missing.

Also notice that this operation doesn't guarantee that tokenAmounts will be invested in full.

**Parameters:**

| Name           | Type       | Description                                                                                                                                                             |
| -------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tokens`       | address\[] | Tokens to push                                                                                                                                                          |
| `tokenAmounts` | uint256\[] | Amounts of tokens to push                                                                                                                                               |
| `options`      | bytes      | Additional options that could be needed for some vaults. E.g. for Uniswap this could be `deadline` param. For the exact bytes structure see concrete vault descriptions |

**Return Values:**

| Name                 | Type       | Description                                                                        |
| -------------------- | ---------- | ---------------------------------------------------------------------------------- |
| `actualTokenAmounts` | uint256\[] | The amounts actually invested. It could be less than tokenAmounts (but not higher) |

#### transferAndPush

```solidity
  function transferAndPush(address from, address[] tokens, uint256[] tokenAmounts, bytes options) external returns (uint256[] actualTokenAmounts)
```

The same as `push` method above but transfers tokens to vault balance prior to calling push. After the `push` it returns all the leftover tokens back (`push` method doesn't guarantee that tokenAmounts will be invested in full).

**Parameters:**

| Name           | Type       | Description                                                                                                                                                             |
| -------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tokens`       | address    | Tokens to push                                                                                                                                                          |
| `tokenAmounts` | address\[] | Amounts of tokens to push                                                                                                                                               |
| `options`      | uint256\[] | Additional options that could be needed for some vaults. E.g. for Uniswap this could be `deadline` param. For the exact bytes structure see concrete vault descriptions |

**Return Values:**

| Name                 | Type       | Description                                                                        |
| -------------------- | ---------- | ---------------------------------------------------------------------------------- |
| `actualTokenAmounts` | uint256\[] | The amounts actually invested. It could be less than tokenAmounts (but not higher) |

#### pull

```solidity
  function pull(address to, address[] tokens, uint256[] tokenAmounts, bytes options) external returns (uint256[] actualTokenAmounts)
```

Pulls tokens from the underlying protocol to the `to` address.

📕 Can only be called but Vault Owner or Strategy. Vault owner is the owner of NFT for this vault in VaultManager. Strategy is approved address for the vault NFT. When called by vault owner this method just pulls the tokens from the protocol to the `to` address When called by strategy on vault other than zero vault it pulls the tokens to zero vault (required `to` == zero vault) When called by strategy on zero vault it pulls the tokens to zero vault, pushes tokens on the `to` vault, and reclaims everything that's left. Thus any vault other than zero vault cannot have any tokens on it

Tokens **must** be a subset of Vault Tokens. However, the convention is that if tokenAmount == 0 it is the same as token is missing.

Pull is fulfilled on the best effort basis, i.e. if the tokenAmounts overflows available funds it withdraws all the funds.

**Parameters:**

| Name           | Type       | Description                                                                                                                                                             |
| -------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `to`           | address    | Address to receive the tokens                                                                                                                                           |
| `tokens`       | address\[] | Tokens to pull                                                                                                                                                          |
| `tokenAmounts` | uint256\[] | Amounts of tokens to pull                                                                                                                                               |
| `options`      | bytes      | Additional options that could be needed for some vaults. E.g. for Uniswap this could be `deadline` param. For the exact bytes structure see concrete vault descriptions |

**Return Values:**

| Name                 | Type       | Description                                                                         |
| -------------------- | ---------- | ----------------------------------------------------------------------------------- |
| `actualTokenAmounts` | uint256\[] | The amounts actually withdrawn. It could be less than tokenAmounts (but not higher) |

#### reclaimTokens

```solidity
  function reclaimTokens(address[] tokens) external returns (uint256[] actualTokenAmounts)
```

Claim ERC20 tokens from vault balance to zero vault.

📕 Cannot be called from zero vault.

**Parameters:**

| Name     | Type       | Description     |
| -------- | ---------- | --------------- |
| `tokens` | address\[] | Tokens to claim |

**Return Values:**

| Name                 | Type       | Description       |
| -------------------- | ---------- | ----------------- |
| `actualTokenAmounts` | uint256\[] | Amounts reclaimed |

#### isValidSignature

```solidity
  function isValidSignature(bytes32 _hash, bytes _signature) external returns (bytes4 magicValue)
```

Verifies offchain signature.

📕 Should return whether the signature provided is valid for the provided hash

MUST return the bytes4 magic value 0x1626ba7e when function passes.

MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for solc > 0.5)

MUST allow external calls

**Parameters:**

| Name         | Type    | Description                                 |
| ------------ | ------- | ------------------------------------------- |
| `_hash`      | bytes32 | Hash of the data to be signed               |
| `_signature` | bytes   | Signature byte array associated with \_hash |

**Return Values:**

| Name         | Type   | Description                               |
| ------------ | ------ | ----------------------------------------- |
| `magicValue` | bytes4 | 0x1626ba7e if valid, 0xffffffff otherwise |

#### externalCall

```solidity
  function externalCall(address to, bytes4 selector, bytes data) external returns (bytes result)
```

Execute one of whitelisted calls.

📕 Can only be called by Vault Owner or Strategy. Vault owner is the owner of NFT for this vault in VaultManager. Strategy is approved address for the vault NFT.

Since this method allows sending arbitrary transactions, the destinations of the calls are whitelisted by Protocol Governance.

**Parameters:**

| Name       | Type    | Description                              |
| ---------- | ------- | ---------------------------------------- |
| `to`       | address | Address of the reward pool               |
| `selector` | bytes4  | Selector of the call                     |
| `data`     | bytes   | Abi encoded parameters to `to::selector` |

**Return Values:**

| Name     | Type  | Description                     |
| -------- | ----- | ------------------------------- |
| `result` | bytes | Result of execution of the call |

### Events

#### Push

```solidity
  event Push(uint256[] tokenAmounts)
```

Emitted on successful push

**Parameters:**

| Name           | Type       | Description                     |
| -------------- | ---------- | ------------------------------- |
| `tokenAmounts` | uint256\[] | The amounts of tokens to pushed |

#### Pull

```solidity
  event Pull(address to, uint256[] tokenAmounts)
```

Emitted on successful pull

**Parameters:**

| Name           | Type       | Description                          |
| -------------- | ---------- | ------------------------------------ |
| `to`           | address    | The target address for pulled tokens |
| `tokenAmounts` | uint256\[] | The amounts of tokens to pull        |

#### ReclaimTokens

```solidity
  event ReclaimTokens(address to, address[] tokens, uint256[] tokenAmounts)
```

Emitted when tokens are reclaimed

**Parameters:**

| Name           | Type       | Description                          |
| -------------- | ---------- | ------------------------------------ |
| `to`           | address    | The target address for pulled tokens |
| `tokens`       | address\[] | ERC20 tokens to be reclaimed         |
| `tokenAmounts` | uint256\[] | The amounts of reclaims              |

## MellowVault

*Inherits from* [*Vault*](#vault)*,* [*ERC165*](#erc165)*,* [*ReentrancyGuard*](#reentrancyguard)

⛽ 4.91M

Vault that stores ERC20 tokens.

#### tvl

```solidity
  function tvl() public returns (uint256[] minTokenAmounts, uint256[] maxTokenAmounts)
```

Total value locked for this contract.

📕 Generally it is the underlying token value of this contract in some other DeFi protocol. For example, for USDC Yearn Vault this would be total USDC balance that could be withdrawn for Yearn to this contract. The tvl itself is estimated in some range. Sometimes the range is exact, sometimes it's not

**Return Values:**

| Name              | Type       | Description                                                                                                   |
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| `minTokenAmounts` | uint256\[] | Lower bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |
| `maxTokenAmounts` | uint256\[] | Upper bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |

#### initialize

```solidity
  function initialize(uint256 nft_, address[] vaultTokens_, contract IERC20RootVault vault_) external
```

Initialized a new contract.

📕 Can only be initialized by vault governance

**Parameters:**

| Name           | Type                     | Description                                     |
| -------------- | ------------------------ | ----------------------------------------------- |
| `nft_`         | uint256                  | NFT of the vault in the VaultRegistry           |
| `vaultTokens_` | address\[]               | ERC20 tokens that will be managed by this Vault |
| `rootVault_`   | contract IERC20RootVault | Reference to mellow root vault                  |

## MellowVaultGovernance

*Inherits from* [*VaultGovernance*](#vaultgovernance)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 1.6M

Governance that manages all Mellow Vaults params and can deploy a new Mellow Vault.

### Functions

#### constructor

```solidity
  function constructor(struct IVaultGovernance.InternalParams internalParams_) public
```

Creates a new contract.

**Parameters:**

| Name              | Type                                   | Description             |
| ----------------- | -------------------------------------- | ----------------------- |
| `internalParams_` | struct IVaultGovernance.InternalParams | Initial Internal Params |

#### createVault

```solidity
  function createVault(address[] vaultTokens_, address owner_, contract IERC20RootVault underlyingVault) external returns (contract IMellowVault vault, uint256 nft)
```

Deploys a new vault.

**Parameters:**

| Name              | Type                     | Description                                     |
| ----------------- | ------------------------ | ----------------------------------------------- |
| `vaultTokens_`    | address\[]               | ERC20 tokens that will be managed by this Vault |
| `owner_`          | address                  | Owner of the vault NFT                          |
| `underlyingVault` | contract IERC20RootVault | Underlying mellow vault                         |

### Structs

```solidity
struct InternalParams {
    IProtocolGovernance protocolGovernance;
    IVaultRegistry registry;
    IVault singleton;
}
```

## QuickSwapVault

*Inherits from* [*Vault*](#vault)*,* [*ERC165*](#erc165)*,* [*ReentrancyGuard*](#reentrancyguard)

Vault that interfaces QuickSwap protocol in the integration layer.

### Functions

#### constructor

```solidity
  function constructor(contract IAlgebraNonfungiblePositionManager positionManager_, contract IQuickSwapHelper helper_, contract IAlgebraSwapRouter swapRouter_, contract IFarmingCenter farmingCenter_, address dQuickToken_, address quickToken_) public
```

#### initialize

```solidity
  function initialize(uint256 nft_, address erc20Vault_, address[] vaultTokens_) external
```

Initialized a new contract.

📕 Can only be initialized by vault governance

**Parameters:**

| Name           | Type    | Description                                     |
| -------------- | ------- | ----------------------------------------------- |
| `nft_`         | uint256 | NFT of the vault in the VaultRegistry           |
| `vaultTokens_` | address | ERC20 tokens that will be managed by this Vault |

#### onERC721Received

```solidity
  function onERC721Received(address operator, address from, uint256 tokenId, bytes) external returns (bytes4)
```

📕 Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.

#### openFarmingPosition

```solidity
  function openFarmingPosition(uint256 nft, contract IFarmingCenter farmingCenter_) public
```

**Parameters:**

| Name             | Type                    | Description                                                                                 |
| ---------------- | ----------------------- | ------------------------------------------------------------------------------------------- |
| `nft`            | uint256                 | nft position of quickswap protocol                                                          |
| `farmingCenter_` | contract IFarmingCenter | Algebra main farming contract. Manages farmings and performs entry, exit and other actions. |

#### burnFarmingPosition

```solidity
  function burnFarmingPosition(uint256 nft, contract IFarmingCenter farmingCenter_) public
```

**Parameters:**

| Name             | Type                    | Description                                                                                 |
| ---------------- | ----------------------- | ------------------------------------------------------------------------------------------- |
| `nft`            | uint256                 | nft position of quickswap protocol                                                          |
| `farmingCenter_` | contract IFarmingCenter | Algebra main farming contract. Manages farmings and performs entry, exit and other actions. |

#### collectEarnings

⛽ 135K (121K - 195K)

```solidity
  function collectEarnings() external returns (uint256[] collectedFees)
```

**Return Values:**

| Name            | Type       | Description                                                                                            |
| --------------- | ---------- | ------------------------------------------------------------------------------------------------------ |
| `collectedFees` | uint256\[] | array of length 2 with amounts of collected and transferred fees from Quickswap position to ERC20Vault |

#### collectRewards

```solidity
  function collectRewards() public returns (uint256[] collectedRewards)
```

**Parameters:**

| Name               | Type | Description                                    |
| ------------------ | ---- | ---------------------------------------------- |
| `collectedRewards` |      | amount of collected tokes in underlying tokens |

#### tvl

```solidity
  function tvl() public returns (uint256[] minTokenAmounts, uint256[] maxTokenAmounts)
```

Total value locked for this contract.

📕 Generally it is the underlying token value of this contract in some other DeFi protocol. For example, for USDC Yearn Vault this would be total USDC balance that could be withdrawn for Yearn to this contract. The tvl itself is estimated in some range. Sometimes the range is exact, sometimes it's not

**Return Values:**

| Name              | Type       | Description                                                                                                   |
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| `minTokenAmounts` | uint256\[] | Lower bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |
| `maxTokenAmounts` | uint256\[] | Upper bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

#### strategyParams

```solidity
  function strategyParams() public returns (struct IQuickSwapVaultGovernance.StrategyParams params)
```

**Return Values:**

| Name     | Type                                            | Description                  |
| -------- | ----------------------------------------------- | ---------------------------- |
| `params` | struct IQuickSwapVaultGovernance.StrategyParams | strategy params of the vault |

### Events

#### CollectedEarnings

```solidity
  event CollectedEarnings(address origin, address sender, uint256 amount0, uint256 amount1)
```

Emitted when earnings are collected

**Parameters:**

| Name      | Type    | Description                           |
| --------- | ------- | ------------------------------------- |
| `origin`  | address | Origin of the transaction (tx.origin) |
| `sender`  | address | Sender of the call (msg.sender)       |
| `amount0` | uint256 | Amount of token0 collected            |
| `amount1` | uint256 | Amount of token1 collected            |

#### CollectedRewards

```solidity
  event CollectedRewards(address origin, address sender, uint256 amount0, uint256 amount1)
```

Emitted when rewards are collected

**Parameters:**

| Name      | Type    | Description                                 |
| --------- | ------- | ------------------------------------------- |
| `origin`  | address | Origin of the transaction (tx.origin)       |
| `sender`  | address | Sender of the call (msg.sender)             |
| `amount0` | uint256 | Amount of collected rewardTokenToUnderlying |
| `amount1` | uint256 | Amount of collected bonusTokenToUnderlying  |

## QuickSwapVaultGovernance

*Inherits from* [*VaultGovernance*](#vaultgovernance)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

Governance that manages all QuickSwap Vaults params and can deploy a new QuickSwap Vault.

### Functions

#### constructor

```solidity
  function constructor(struct IVaultGovernance.InternalParams internalParams_) public
```

Creates a new contract.

**Parameters:**

| Name              | Type                                   | Description             |
| ----------------- | -------------------------------------- | ----------------------- |
| `internalParams_` | struct IVaultGovernance.InternalParams | Initial Internal Params |

#### strategyParams

```solidity
  function strategyParams(uint256 nft) external returns (struct IQuickSwapVaultGovernance.StrategyParams)
```

Delayed Strategy Params

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

#### setStrategyParams

```solidity
  function setStrategyParams(uint256 nft, struct IQuickSwapVaultGovernance.StrategyParams params) external
```

Delayed Strategy Params staged for commit after delay.

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

#### createVault

```solidity
  function createVault(address[] vaultTokens_, address owner_, address erc20Vault_) external returns (contract IQuickSwapVault vault, uint256 nft)
```

Deploys a new vault.

**Parameters:**

| Name               | Type       | Description                                     |
| ------------------ | ---------- | ----------------------------------------------- |
| `vaultTokens_`     | address\[] | ERC20 tokens that will be managed by this Vault |
| `owner_`           | address    | Owner of the vault NFT                          |
| `quickSwapHelper_` | address    | address of helper                               |

### Structs

```solidity
struct StrategyParams {
    struct IIncentiveKey.IncentiveKey key;
    address bonusTokenToUnderlying;
    address rewardTokenToUnderlying;
    uint256 swapSlippageD;
    uint32 rewardPoolTimespan;
}
```

```solidity
struct InternalParams {
    IProtocolGovernance protocolGovernance;
    IVaultRegistry registry;
    IVault singleton;
}
```

### Events

#### SetStrategyParams

```solidity
  event SetStrategyParams(address origin, address sender, uint256 nft, struct IQuickSwapVaultGovernance.StrategyParams params)
```

Emitted when new StrategyParams are set

**Parameters:**

| Name     | Type                                            | Description                           |
| -------- | ----------------------------------------------- | ------------------------------------- |
| `origin` | address                                         | Origin of the transaction (tx.origin) |
| `sender` | address                                         | Sender of the call (msg.sender)       |
| `nft`    | uint256                                         | VaultRegistry NFT of the vault        |
| `params` | struct IQuickSwapVaultGovernance.StrategyParams | New set params                        |

## UniV3Vault

*Inherits from* [*Vault*](#vault)*,* [*ERC165*](#erc165)*,* [*ReentrancyGuard*](#reentrancyguard)

⛽ 6.61M

Vault that interfaces UniswapV3 protocol in the integration layer.

### Functions

#### tvl

```solidity
  function tvl() public returns (uint256[] minTokenAmounts, uint256[] maxTokenAmounts)
```

Total value locked for this contract.

📕 Generally it is the underlying token value of this contract in some other DeFi protocol. For example, for USDC Yearn Vault this would be total USDC balance that could be withdrawn for Yearn to this contract. The tvl itself is estimated in some range. Sometimes the range is exact, sometimes it's not

**Return Values:**

| Name              | Type       | Description                                                                                                   |
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| `minTokenAmounts` | uint256\[] | Lower bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |
| `maxTokenAmounts` | uint256\[] | Upper bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |

**Specs**

* ✅ returns total value locked
* ✅ edge cases: when there are no initial funds returns zeroes
* ✅ edge cases: when push was made but there was no minted position returns zeroes

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true if this contract supports 0x88878d28 interface
* ✅ access control: allowed: any address
* ✅ returns true if this contract supports 0x7a63aa3a interface
* ✅ access control: allowed: any address
* ✅ edge cases: when contract does not support the given interface returns false

#### positionManager

```solidity
  function positionManager() external returns (contract INonfungiblePositionManager)
```

Reference to INonfungiblePositionManager of UniswapV3 protocol.

**Specs**

* ✅ returns INonfungiblePositionManager
* ✅ access control: allowed: any address

#### liquidityToTokenAmounts

```solidity
  function liquidityToTokenAmounts(uint128 liquidity) external returns (uint256[] tokenAmounts)
```

Returns tokenAmounts corresponding to liquidity, based on the current Uniswap position

**Parameters:**

| Name        | Type    | Description                                       |
| ----------- | ------- | ------------------------------------------------- |
| `liquidity` | uint128 | Liquidity that will be converted to token amounts |

**Return Values:**

| Name           | Type       | Description                               |
| -------------- | ---------- | ----------------------------------------- |
| `tokenAmounts` | uint256\[] | Token amounts for the specified liquidity |

**Specs**

* ✅ returns tokenAmounts corresponding to liquidity

#### tokenAmountsToLiquidity

```solidity
  function tokenAmountsToLiquidity(uint256[] tokenAmounts) public returns (uint128 liquidity)
```

Returns liquidity corresponding to token amounts, based on the current Uniswap position

**Parameters:**

| Name           | Type       | Description                                       |
| -------------- | ---------- | ------------------------------------------------- |
| `tokenAmounts` | uint256\[] | Token amounts that will be converted to liquidity |

**Return Values:**

| Name        | Type    | Description                               |
| ----------- | ------- | ----------------------------------------- |
| `liquidity` | uint128 | Liquidity for the specified token amounts |

**Specs**

* ✅ returns zero in case of zero amounts
* ✅ returns more than zero in case of non-zero amounts
* ✅ returns proportionally correct
* ✅ returns correctly in case of tick being out of position by the left
* ✅ returns correctly in case of tick being out of position by the right

#### initialize

⛽ 186K

```solidity
  function initialize(uint256 nft_, address[] vaultTokens_, uint24 fee_, address uniV3Hepler_) external
```

Initialized a new contract.

📕 Can only be initialized by vault governance

**Parameters:**

| Name           | Type       | Description                                       |
| -------------- | ---------- | ------------------------------------------------- |
| `nft_`         | uint256    | NFT of the vault in the VaultRegistry             |
| `vaultTokens_` | address\[] | ERC20 tokens that will be managed by this Vault   |
| `fee_`         | uint24     | Fee of the UniV3 pool                             |
| `uniV3Helper_` | address    | address of helper for UniV3 arithmetic with ticks |

**Specs**

* ✅ emits Initialized event
* ✅ initializes contract successfully
* ✅ edge cases: when vault's nft is not 0 reverts with INIT
* ✅ edge cases: when tokens are not sorted reverts with INVA
* ✅ edge cases: when tokens are not unique reverts with INVA
* ✅ edge cases: when tokens length is not equal to 2 reverts with INV
* ✅ edge cases: when setting zero nft reverts with VZ
* ✅ edge cases: when token has no permission to become a vault token reverts with FRB

#### onERC721Received

```solidity
  function onERC721Received(address operator, address from, uint256 tokenId, bytes) external returns (bytes4)
```

📕 Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} by `operator` from `from`, this function is called. It must return its Solidity selector to confirm the token transfer. If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`.

**Specs**

* ✅ updates vault's uniV3Nft
* ✅ edge cases: when msg.sender is not a position manager reverts
* ✅ edge cases: when operator is not a strategy reverts
* ✅ edge cases: when UniV3 token is not valid reverts
* ✅ edge cases: prevent from adding nft while liquidity is not empty reverts
* ✅ access control: position manager: allowed
* ✅ access control: any other address: not allowed

#### collectEarnings

```solidity
  function collectEarnings() external returns (uint256[] collectedEarnings)
```

Collect UniV3 fees to zero vault.

**Specs**

* ✅ emits CollectedEarnings event
* ✅ collecting fees
* ✅ edge cases: when there is no minted position reverts
* ✅ access control: allowed: all addresses

### Structs

```solidity
struct Pair {
    uint256 a0;
    uint256 a1;
}
```

```solidity
struct Options {
    uint256 amount0Min;
    uint256 amount1Min;
    uint256 deadline;
}
```

### Events

#### CollectedEarnings

```solidity
  event CollectedEarnings(address origin, address sender, address to, uint256 amount0, uint256 amount1)
```

Emitted when earnings are collected

**Parameters:**

| Name      | Type    | Description                           |
| --------- | ------- | ------------------------------------- |
| `origin`  | address | Origin of the transaction (tx.origin) |
| `sender`  | address | Sender of the call (msg.sender)       |
| `to`      | address | Receiver of the fees                  |
| `amount0` | uint256 | Amount of token0 collected            |
| `amount1` | uint256 | Amount of token1 collected            |

## UniV3VaultGovernance

*Inherits from* [*VaultGovernance*](#vaultgovernance)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 3.02M

Governance that manages all UniV3 Vaults params and can deploy a new UniV3 Vault.

### Functions

#### constructor

```solidity
  function constructor(struct IVaultGovernance.InternalParams internalParams_, struct IUniV3VaultGovernance.DelayedProtocolParams delayedProtocolParams_) public
```

Creates a new contract.

**Parameters:**

| Name                     | Type                                               | Description             |
| ------------------------ | -------------------------------------------------- | ----------------------- |
| `internalParams_`        | struct IVaultGovernance.InternalParams             | Initial Internal Params |
| `delayedProtocolParams_` | struct IUniV3VaultGovernance.DelayedProtocolParams | Initial Protocol Params |

**Specs**

* ✅ deploys a new contract
* ✅ initializes internalParams

*Edge cases*

* ✅ when positionManager address is 0 reverts
* ✅ when oracle address is 0 reverts
* ✅ when protocolGovernance address is 0 reverts
* ✅ when vaultRegistry address is 0 reverts

#### delayedProtocolParams

```solidity
  function delayedProtocolParams() public returns (struct IUniV3VaultGovernance.DelayedProtocolParams)
```

Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Specs**

* ✅ returns current DelayedProtocolParams

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ staging DelayedProtocolParams doesn't change delayedProtocolParams

*Edge cases*

* ✅ when no params were committed returns non-zero params initialized in constructor

#### stagedDelayedProtocolParams

```solidity
  function stagedDelayedProtocolParams() external returns (struct IUniV3VaultGovernance.DelayedProtocolParams)
```

Delayed Protocol Params staged for commit after delay.

**Specs**

* ✅ returns DelayedProtocolParams staged for commit

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ always equals to params that were just staged

*Edge cases*

* ✅ when no params are staged for commit returns zero struct
* ✅ when params were just committed returns zero struct

#### stagedDelayedStrategyParams

```solidity
  function stagedDelayedStrategyParams(uint256 nft) external returns (struct IUniV3VaultGovernance.DelayedStrategyParams)
```

Delayed Strategy Params staged for commit after delay.

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

#### delayedStrategyParams

```solidity
  function delayedStrategyParams(uint256 nft) external returns (struct IUniV3VaultGovernance.DelayedStrategyParams)
```

Delayed Strategy Params

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true if this contract supports 0xa2e9c513 interface
* ✅ access control: allowed: any address

#### stageDelayedProtocolParams

⛽ 88K (52K - 129K)

```solidity
  function stageDelayedProtocolParams(struct IUniV3VaultGovernance.DelayedProtocolParams params) external
```

Stage Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Parameters:**

| Name     | Type                                               | Description |
| -------- | -------------------------------------------------- | ----------- |
| `params` | struct IUniV3VaultGovernance.DelayedProtocolParams | New params  |

**Specs**

* ✅ stages DelayedProtocolParams for commit
* ✅ sets delay for commit
* ✅ emits StageDelayedProtocolParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ denied: Vault NFT Owner (aka liquidity provider)
* ✅ denied: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address

*Edge cases*

* ✅ when called twice succeeds with the last value
* ✅ when called with zero params reverts with zero params

#### commitDelayedProtocolParams

⛽ 50K (50K - 54K)

```solidity
  function commitDelayedProtocolParams() external
```

Commit Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Specs**

* ✅ commits staged DelayedProtocolParams
* ✅ resets delay for commit
* ✅ emits CommitDelayedProtocolParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ denied: Vault NFT Owner (aka liquidity provider)
* ✅ denied: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address
* ✅ reverts if called before the delay has elapsed
* ✅ succeeds if called after the delay has elapsed

*Edge cases*

* ✅ when called twice reverts
* ✅ when nothing is staged reverts
* ✅ when delay has not elapsed reverts

#### stageDelayedStrategyParams

⛽ 121K

```solidity
  function stageDelayedStrategyParams(uint256 nft, struct IUniV3VaultGovernance.DelayedStrategyParams params) external
```

Stage Delayed Strategy Params, i.e. Params that could be changed by Strategy or Protocol Governance with Protocol Governance delay.

**Parameters:**

| Name     | Type                                               | Description                    |
| -------- | -------------------------------------------------- | ------------------------------ |
| `nft`    | uint256                                            | VaultRegistry NFT of the vault |
| `params` | struct IUniV3VaultGovernance.DelayedStrategyParams | New params                     |

#### commitDelayedStrategyParams

⛽ 94K

```solidity
  function commitDelayedStrategyParams(uint256 nft) external
```

Commit Delayed Strategy Params, i.e. Params that could be changed by Strategy or Protocol Governance with Protocol Governance delay.

📕 Can only be called after delayedStrategyParamsTimestamp

**Parameters:**

| Name  | Type    | Description                    |
| ----- | ------- | ------------------------------ |
| `nft` | uint256 | VaultRegistry NFT of the vault |

#### createVault

⛽ 563K (550K - 577K)

```solidity
  function createVault(address[] vaultTokens_, address owner_, uint24 fee_, address uniV3Helper_) external returns (contract IUniV3Vault vault, uint256 nft)
```

Deploys a new vault.

**Parameters:**

| Name           | Type       | Description                                       |
| -------------- | ---------- | ------------------------------------------------- |
| `vaultTokens_` | address\[] | ERC20 tokens that will be managed by this Vault   |
| `owner_`       | address    | Owner of the vault NFT                            |
| `fee_`         | uint24     | Fee of the UniV3 pool                             |
| `uniV3Helper_` | address    | address of helper for UniV3 arithmetic with ticks |

**Specs**

* ✅ deploys a new vault
* ✅ registers vault with vault registry and issues nft
* ✅ the nft is owned by the owner from #createVault arguments
* ✅ vault is initialized with nft

*Access control*

* ✅ when permissionless allowed: any address
* ✅ when not permissionless allowed: protocol governance admin
* ✅ when not permissionless denied: any address

*Edge cases*

* ✅ when fee is not supported by uni v3 reverts

### Structs

```solidity
struct DelayedProtocolParams {
    INonfungiblePositionManager positionManager;
    IOracle oracle;
}
```

```solidity
struct DelayedStrategyParams {
    uint32 safetyIndicesSet;
}
```

```solidity
struct InternalParams {
    IProtocolGovernance protocolGovernance;
    IVaultRegistry registry;
    IVault singleton;
}
```

### Events

#### StageDelayedProtocolParams

```solidity
  event StageDelayedProtocolParams(address origin, address sender, struct IUniV3VaultGovernance.DelayedProtocolParams params, uint256 when)
```

Emitted when new DelayedProtocolParams are staged for commit

**Parameters:**

| Name     | Type                                               | Description                            |
| -------- | -------------------------------------------------- | -------------------------------------- |
| `origin` | address                                            | Origin of the transaction (tx.origin)  |
| `sender` | address                                            | Sender of the call (msg.sender)        |
| `params` | struct IUniV3VaultGovernance.DelayedProtocolParams | New params that were staged for commit |
| `when`   | uint256                                            | When the params could be committed     |

#### CommitDelayedProtocolParams

```solidity
  event CommitDelayedProtocolParams(address origin, address sender, struct IUniV3VaultGovernance.DelayedProtocolParams params)
```

Emitted when new DelayedProtocolParams are committed

**Parameters:**

| Name     | Type                                               | Description                           |
| -------- | -------------------------------------------------- | ------------------------------------- |
| `origin` | address                                            | Origin of the transaction (tx.origin) |
| `sender` | address                                            | Sender of the call (msg.sender)       |
| `params` | struct IUniV3VaultGovernance.DelayedProtocolParams | New params that are committed         |

#### StageDelayedStrategyParams

```solidity
  event StageDelayedStrategyParams(address origin, address sender, uint256 nft, struct IUniV3VaultGovernance.DelayedStrategyParams params, uint256 when)
```

Emitted when new DelayedStrategyParams are staged for commit

**Parameters:**

| Name     | Type                                               | Description                            |
| -------- | -------------------------------------------------- | -------------------------------------- |
| `origin` | address                                            | Origin of the transaction (tx.origin)  |
| `sender` | address                                            | Sender of the call (msg.sender)        |
| `nft`    | uint256                                            | VaultRegistry NFT of the vault         |
| `params` | struct IUniV3VaultGovernance.DelayedStrategyParams | New params that were staged for commit |
| `when`   | uint256                                            | When the params could be committed     |

#### CommitDelayedStrategyParams

```solidity
  event CommitDelayedStrategyParams(address origin, address sender, uint256 nft, struct IUniV3VaultGovernance.DelayedStrategyParams params)
```

Emitted when new DelayedStrategyParams are committed

**Parameters:**

| Name     | Type                                               | Description                           |
| -------- | -------------------------------------------------- | ------------------------------------- |
| `origin` | address                                            | Origin of the transaction (tx.origin) |
| `sender` | address                                            | Sender of the call (msg.sender)       |
| `nft`    | uint256                                            | VaultRegistry NFT of the vault        |
| `params` | struct IUniV3VaultGovernance.DelayedStrategyParams | New params that are committed         |

## Vault

*Inherits from* [*ERC165*](#erc165)

Abstract contract that has logic common for every Vault.

📕 Notes:

#### ERC-721

Each Vault should be registered in VaultRegistry and get corresponding VaultRegistry NFT.

#### Access control

`push` and `pull` methods are only allowed for owner / approved person of the NFT. However, `pull` for approved person also checks that pull destination is another vault of the Vault System.

The semantics is: NFT owner owns all Vault liquidity, Approved person is liquidity manager. ApprovedForAll person cannot do anything except ERC-721 token transfers.

Both NFT owner and approved person can call externalCall method which claims liquidity mining rewards (if any)

`reclaimTokens` for mistakenly transfered tokens (not included into vaultTokens) additionally can be withdrawn by the protocol admin

### Functions

#### initialized

```solidity
  function initialized() external returns (bool)
```

Checks if the vault is initialized

#### isVaultToken

```solidity
  function isVaultToken(address token) public returns (bool)
```

Checks if a token is vault token

**Parameters:**

| Name    | Type    | Description                   |
| ------- | ------- | ----------------------------- |
| `token` | address | Address of the token to check |

**Return Values:**

| Name | Type | Description                    |
| ---- | ---- | ------------------------------ |
| `if` | bool | this token is managed by Vault |

#### vaultGovernance

```solidity
  function vaultGovernance() external returns (contract IVaultGovernance)
```

Address of the Vault Governance for this contract.

#### vaultTokens

```solidity
  function vaultTokens() external returns (address[])
```

ERC20 tokens under Vault management.

#### nft

```solidity
  function nft() external returns (uint256)
```

VaultRegistry NFT for this vault

#### tvl

```solidity
  function tvl() public returns (uint256[] minTokenAmounts, uint256[] maxTokenAmounts)
```

Total value locked for this contract.

📕 Generally it is the underlying token value of this contract in some other DeFi protocol. For example, for USDC Yearn Vault this would be total USDC balance that could be withdrawn for Yearn to this contract. The tvl itself is estimated in some range. Sometimes the range is exact, sometimes it's not

**Return Values:**

| Name              | Type       | Description                                                                                                   |
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| `minTokenAmounts` | uint256\[] | Lower bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |
| `maxTokenAmounts` | uint256\[] | Upper bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |

#### pullExistentials

```solidity
  function pullExistentials() external returns (uint256[])
```

Existential amounts for each token

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

### Events

#### Initialized

```solidity
  event Initialized(address origin, address sender, address[] vaultTokens_, uint256 nft_)
```

Emitted when Vault is intialized

**Parameters:**

| Name           | Type       | Description                             |
| -------------- | ---------- | --------------------------------------- |
| `origin`       | address    | Origin of the transaction (tx.origin)   |
| `sender`       | address    | Sender of the call (msg.sender)         |
| `vaultTokens_` | address\[] | ERC20 tokens under the vault management |
| `nft_`         | uint256    | VaultRegistry NFT assigned to the vault |

## VaultGovernance

*Inherits from* [*ERC165*](#erc165)

Internal contract for managing different params.

📕 The contract should be overriden by the concrete VaultGovernance, define different params structs and use abi.decode / abi.encode to serialize to bytes in this contract. It also should emit events on params change.

### Functions

#### delayedStrategyParamsTimestamp

```solidity
  function delayedStrategyParamsTimestamp(uint256 nft) external returns (uint256)
```

Timestamp in unix time seconds after which staged Delayed Strategy Params could be committed.

**Parameters:**

| Name  | Type    | Description      |
| ----- | ------- | ---------------- |
| `nft` | uint256 | Nft of the vault |

#### delayedProtocolPerVaultParamsTimestamp

```solidity
  function delayedProtocolPerVaultParamsTimestamp(uint256 nft) external returns (uint256)
```

Timestamp in unix time seconds after which staged Delayed Protocol Params Per Vault could be committed.

**Parameters:**

| Name  | Type    | Description      |
| ----- | ------- | ---------------- |
| `nft` | uint256 | Nft of the vault |

#### delayedProtocolParamsTimestamp

```solidity
  function delayedProtocolParamsTimestamp() external returns (uint256)
```

Timestamp in unix time seconds after which staged Delayed Protocol Params could be committed.

#### internalParamsTimestamp

```solidity
  function internalParamsTimestamp() external returns (uint256)
```

Timestamp in unix time seconds after which staged Internal Params could be committed.

#### internalParams

```solidity
  function internalParams() external returns (struct IVaultGovernance.InternalParams)
```

Internal Params of the contract.

#### stagedInternalParams

```solidity
  function stagedInternalParams() external returns (struct IVaultGovernance.InternalParams)
```

Staged new Internal Params.

📕 The Internal Params could be committed after internalParamsTimestamp

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceID) public returns (bool)
```

#### stageInternalParams

```solidity
  function stageInternalParams(struct IVaultGovernance.InternalParams newParams) external
```

Stage new Internal Params.

**Parameters:**

| Name        | Type                                   | Description         |
| ----------- | -------------------------------------- | ------------------- |
| `newParams` | struct IVaultGovernance.InternalParams | New Internal Params |

#### commitInternalParams

```solidity
  function commitInternalParams() external
```

Commit staged Internal Params.

### Structs

```solidity
struct InternalParams {
    IProtocolGovernance protocolGovernance;
    IVaultRegistry registry;
    IVault singleton;
}
```

### Events

#### StagedInternalParams

```solidity
  event StagedInternalParams(address origin, address sender, struct IVaultGovernance.InternalParams params, uint256 when)
```

Emitted when InternalParams are staged for commit

**Parameters:**

| Name     | Type                                   | Description                            |
| -------- | -------------------------------------- | -------------------------------------- |
| `origin` | address                                | Origin of the transaction (tx.origin)  |
| `sender` | address                                | Sender of the call (msg.sender)        |
| `params` | struct IVaultGovernance.InternalParams | New params that were staged for commit |
| `when`   | uint256                                | When the params could be committed     |

#### CommitedInternalParams

```solidity
  event CommitedInternalParams(address origin, address sender, struct IVaultGovernance.InternalParams params)
```

Emitted when InternalParams are staged for commit

**Parameters:**

| Name     | Type                                   | Description                            |
| -------- | -------------------------------------- | -------------------------------------- |
| `origin` | address                                | Origin of the transaction (tx.origin)  |
| `sender` | address                                | Sender of the call (msg.sender)        |
| `params` | struct IVaultGovernance.InternalParams | New params that were staged for commit |

#### DeployedVault

```solidity
  event DeployedVault(address origin, address sender, address[] vaultTokens, bytes options, address owner, address vaultAddress, uint256 vaultNft)
```

Emitted when New Vault is deployed

**Parameters:**

| Name           | Type       | Description                                                                            |
| -------------- | ---------- | -------------------------------------------------------------------------------------- |
| `origin`       | address    | Origin of the transaction (tx.origin)                                                  |
| `sender`       | address    | Sender of the call (msg.sender)                                                        |
| `vaultTokens`  | address\[] | Vault tokens for this vault                                                            |
| `options`      | bytes      | Options for deploy. The details of the options structure are specified in subcontracts |
| `owner`        | address    | Owner of the VaultRegistry NFT for this vault                                          |
| `vaultAddress` | address    | Address of the new Vault                                                               |
| `vaultNft`     | uint256    | VaultRegistry NFT for the new Vault                                                    |

## YearnVault

*Inherits from* [*Vault*](#vault)*,* [*ERC165*](#erc165)*,* [*ReentrancyGuard*](#reentrancyguard)

⛽ 4.81M

Vault that interfaces Yearn protocol in the integration layer.

📕 Notes: **TVL**

The TVL of the vault is updated after each deposit withdraw.

**yTokens** yTokens are fixed at the token creation and addresses are taken from YearnVault governance and if missing there

* in YearnVaultRegistry. So essentially each yToken is fixed for life of the YearnVault. If the yToken is missing for some vaultToken, the YearnVault cannot be created.

**Push / Pull** There are some deposit limits imposed by Yearn vaults. The contract's vaultTokens are fully allowed to corresponding yTokens.

#### yTokens

```solidity
  function yTokens() external returns (address[])
```

Yearn protocol vaults used by this contract

**Specs**

* ✅ returns list of yTokens

#### tvl

```solidity
  function tvl() public returns (uint256[] minTokenAmounts, uint256[] maxTokenAmounts)
```

Total value locked for this contract.

📕 Generally it is the underlying token value of this contract in some other DeFi protocol. For example, for USDC Yearn Vault this would be total USDC balance that could be withdrawn for Yearn to this contract. The tvl itself is estimated in some range. Sometimes the range is exact, sometimes it's not

**Return Values:**

| Name              | Type       | Description                                                                                                   |
| ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| `minTokenAmounts` | uint256\[] | Lower bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |
| `maxTokenAmounts` | uint256\[] | Upper bound for total available balances estimation (nth tokenAmount corresponds to nth token in vaultTokens) |

**Specs**

* ✅ returns total value locked
* ✅ edge cases: when there are no initial funds returns zeroes

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true if this contract supports 0x073ab565 interface
* ✅ access control: allowed: any address
* ✅ returns true if this contract supports 0x7a63aa3a interface
* ✅ access control: allowed: any address
* ✅ edge cases: when contract does not support the given interface returns false

#### initialize

```solidity
  function initialize(uint256 nft_, address[] vaultTokens_) external
```

Initialized a new contract.

📕 Can only be initialized by vault governance

**Parameters:**

| Name           | Type       | Description                                     |
| -------------- | ---------- | ----------------------------------------------- |
| `nft_`         | uint256    | NFT of the vault in the VaultRegistry           |
| `vaultTokens_` | address\[] | ERC20 tokens that will be managed by this Vault |

**Specs**

* ✅ emits Initialized event
* ✅ initializes contract successfully
* ✅ edge cases: when vault's nft is not 0 reverts with INIT
* ✅ edge cases: when tokens are not sorted reverts with INVA
* ✅ edge cases: when tokens are not unique reverts with INVA
* ✅ edge cases: when setting zero nft reverts with VZ
* ✅ edge cases: when token has no permission to become a vault token reverts with FRB

## YearnVaultGovernance

*Inherits from* [*VaultGovernance*](#vaultgovernance)*,* [*ERC165*](#erc165)*,* [*ContractMeta*](#contractmeta)

⛽ 2.4M

Governance that manages all Aave Vaults params and can deploy a new Aave Vault.

### Functions

#### constructor

```solidity
  function constructor(struct IVaultGovernance.InternalParams internalParams_, struct IYearnVaultGovernance.DelayedProtocolParams delayedProtocolParams_) public
```

Creates a new contract

**Parameters:**

| Name                     | Type                                               | Description             |
| ------------------------ | -------------------------------------------------- | ----------------------- |
| `internalParams_`        | struct IVaultGovernance.InternalParams             | Initial Internal Params |
| `delayedProtocolParams_` | struct IYearnVaultGovernance.DelayedProtocolParams | Initial Protocol Params |

**Specs**

* ✅ deploys a new contract
* ✅ initializes internalParams

*Edge cases*

* ✅ when YearnVaultRegistry address is 0 reverts
* ✅ when protocolGovernance address is 0 reverts
* ✅ when vaultRegistry address is 0 reverts

#### yTokenForToken

```solidity
  function yTokenForToken(address token) external returns (address)
```

Determines a corresponding Yearn vault for token

**Parameters:**

| Name    | Type    | Description                 |
| ------- | ------- | --------------------------- |
| `token` | address | ERC-20 token for the yToken |

**Return Values:**

| Name | Type    | Description                                               |
| ---- | ------- | --------------------------------------------------------- |
| `If` | address | there's a yToken returns its address, otherwise returns 0 |

**Specs**

* ✅ returns yToken (yVault) in yToken overrides (set by #setYTokenForToken) or corresponding to ERC20 token in YearnVaultRegistry

*Access control*

* ✅ allowed: any address

*Edge cases*

* ✅ when yToken doesn't exist in overrides or YearnVaultRegistry returns 0
* ✅ when yToken was not overridden by #setYTokenForToken returns token from YearnVaultRegistry
* ✅ when yToken was overridden by #setYTokenForToken returns overridden token

#### stagedDelayedProtocolParams

```solidity
  function stagedDelayedProtocolParams() external returns (struct IYearnVaultGovernance.DelayedProtocolParams)
```

Delayed Protocol Params staged for commit after delay.

**Specs**

* ✅ returns DelayedProtocolParams staged for commit

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ always equals to params that were just staged

*Edge cases*

* ✅ when no params are staged for commit returns zero struct
* ✅ when params were just committed returns zero struct

#### delayedProtocolParams

```solidity
  function delayedProtocolParams() public returns (struct IYearnVaultGovernance.DelayedProtocolParams)
```

Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Specs**

* ✅ returns current DelayedProtocolParams

*Access control*

* ✅ allowed: any address

*Properties*

* ✅ staging DelayedProtocolParams doesn't change delayedProtocolParams

*Edge cases*

* ✅ when no params were committed returns non-zero params initialized in constructor

#### supportsInterface

```solidity
  function supportsInterface(bytes4 interfaceId) public returns (bool)
```

📕 Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding <https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified\\[EIP> section] to learn more about how these ids are created. This function call must use less than 30 000 gas.

**Specs**

* ✅ returns true if this contract supports 0x15482137 interface
* ✅ access control: allowed: any address

#### stageDelayedProtocolParams

⛽ 75K (49K - 106K)

```solidity
  function stageDelayedProtocolParams(struct IYearnVaultGovernance.DelayedProtocolParams params) external
```

Stage Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

📕 Can only be called after delayedProtocolParamsTimestamp.

**Parameters:**

| Name     | Type                                               | Description |
| -------- | -------------------------------------------------- | ----------- |
| `params` | struct IYearnVaultGovernance.DelayedProtocolParams | New params  |

**Specs**

* ✅ stages DelayedProtocolParams for commit
* ✅ sets delay for commit
* ✅ emits StageDelayedProtocolParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ denied: Vault NFT Owner (aka liquidity provider)
* ✅ denied: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address

*Edge cases*

* ✅ when called twice succeeds with the last value
* ✅ when called with zero params reverts with zero params

#### commitDelayedProtocolParams

⛽ 43K (43K - 45K)

```solidity
  function commitDelayedProtocolParams() external
```

Commit Delayed Protocol Params, i.e. Params that could be changed by Protocol Governance with Protocol Governance delay.

**Specs**

* ✅ commits staged DelayedProtocolParams
* ✅ resets delay for commit
* ✅ emits CommitDelayedProtocolParams event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ denied: Vault NFT Owner (aka liquidity provider)
* ✅ denied: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Properties*

* ✅ cannot be called by random address
* ✅ reverts if called before the delay has elapsed
* ✅ succeeds if called after the delay has elapsed

*Edge cases*

* ✅ when called twice reverts
* ✅ when nothing is staged reverts
* ✅ when delay has not elapsed reverts

#### setYTokenForToken

⛽ 51K (35K - 56K)

```solidity
  function setYTokenForToken(address token, address yToken) external
```

Sets the manual override for yToken vaults map

📕 Can only be called by Protocol Admin

**Parameters:**

| Name     | Type    | Description             |
| -------- | ------- | ----------------------- |
| `token`  | address | ERC-20 token for yToken |
| `yToken` | address | for ERC-20 token        |

**Specs**

* ✅ sets a yToken override for a ERC20 token
* ✅ emits SetYToken event

*Access control*

* ✅ allowed: ProtocolGovernance admin
* ✅ denied: Vault NFT Owner (aka liquidity provider)
* ✅ denied: Vault NFT Approved (aka strategy)
* ✅ denied: deployer
* ✅ denied: random address

*Edge cases*

* ✅ when yToken is 0 succeeds
* ✅ when called twice succeeds

#### createVault

⛽ 569K (559K - 810K)

```solidity
  function createVault(address[] vaultTokens_, address owner_) external returns (contract IYearnVault vault, uint256 nft)
```

Deploys a new vault.

**Parameters:**

| Name           | Type       | Description                                     |
| -------------- | ---------- | ----------------------------------------------- |
| `vaultTokens_` | address\[] | ERC20 tokens that will be managed by this Vault |
| `owner_`       | address    | Owner of the vault NFT                          |

**Specs**

* ✅ deploys a new vault
* ✅ registers vault with vault registry and issues nft
* ✅ the nft is owned by the owner from #createVault arguments
* ✅ vault is initialized with nft

*Access control*

* ✅ when permissionless allowed: any address
* ✅ when not permissionless allowed: protocol governance admin
* ✅ when not permissionless denied: any address

### Structs

```solidity
struct DelayedProtocolParams {
    IYearnProtocolVaultRegistry yearnVaultRegistry;
}
```

```solidity
struct InternalParams {
    IProtocolGovernance protocolGovernance;
    IVaultRegistry registry;
    IVault singleton;
}
```

### Events

#### SetYToken

```solidity
  event SetYToken(address origin, address sender, address token, address yToken)
```

Emitted when new yToken is set

**Parameters:**

| Name     | Type    | Description                           |
| -------- | ------- | ------------------------------------- |
| `origin` | address | Origin of the transaction (tx.origin) |
| `sender` | address | Sender of the call (msg.sender)       |
| `token`  | address | ERC-20 token for the yToken           |
| `yToken` | address | yToken for ERC-20 token               |

#### StageDelayedProtocolParams

```solidity
  event StageDelayedProtocolParams(address origin, address sender, struct IYearnVaultGovernance.DelayedProtocolParams params, uint256 when)
```

Emitted when new DelayedProtocolParams are staged for commit

**Parameters:**

| Name     | Type                                               | Description                            |
| -------- | -------------------------------------------------- | -------------------------------------- |
| `origin` | address                                            | Origin of the transaction (tx.origin)  |
| `sender` | address                                            | Sender of the call (msg.sender)        |
| `params` | struct IYearnVaultGovernance.DelayedProtocolParams | New params that were staged for commit |
| `when`   | uint256                                            | When the params could be committed     |

#### CommitDelayedProtocolParams

```solidity
  event CommitDelayedProtocolParams(address origin, address sender, struct IYearnVaultGovernance.DelayedProtocolParams params)
```

Emitted when new DelayedProtocolParams are committed

**Parameters:**

| Name     | Type                                               | Description                           |
| -------- | -------------------------------------------------- | ------------------------------------- |
| `origin` | address                                            | Origin of the transaction (tx.origin) |
| `sender` | address                                            | Sender of the call (msg.sender)       |
| `params` | struct IYearnVaultGovernance.DelayedProtocolParams | New params that are committed         |


---

# 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.mellow.finance/mellow-alm/overview/api.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.
