> For the complete documentation index, see [llms.txt](https://devs.maxapy.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://devs.maxapy.io/maxapy-erc4626/vault/maxapyvault.md).

# MaxApyVault

## Overview

The MaxApyVault is an ERC4626-compatible vault contract that serves as the core component of the MaxAPY Protocol. It manages user deposits and strategy allocations to generate yield. The vault accepts deposits of a specific underlying asset, issues share to depositors, and allocates the funds across various yield-generating strategies.

## Constants

```solidity
uint256 public constant MAXIMUM_STRATEGIES = 20;       // Maximum number of strategies the vault can manage
uint256 public constant MAX_BPS = 10_000;             // Base points scale (100%)
uint256 public constant SECS_PER_YEAR = 31_556_952;   // Seconds in a year (365.2425 days)
uint256 public constant AUTOPILOT_HARVEST_INTERVAL = 1 weeks;  // Interval between automated harvests
```

Access Control Roles:

```solidity
uint256 public constant ADMIN_ROLE = _ROLE_0;
uint256 public constant EMERGENCY_ADMIN_ROLE = _ROLE_1;
uint256 public constant STRATEGY_ROLE = _ROLE_2;
```

## Errors

```solidity
error QueueIsFull();                            // Withdrawal queue has reached maximum capacity
error VaultInEmergencyShutdownMode();           // Operation not allowed during emergency shutdown
error StrategyInEmergencyExitMode();            // Strategy is in emergency exit mode
error InvalidZeroAddress();                      // Zero address provided where not allowed
error StrategyAlreadyActive();                  // Attempt to add already active strategy
error StrategyNotActive();                      // Operation attempted on inactive strategy
error InvalidStrategyVault();                   // Strategy's vault address doesn't match
error InvalidStrategyUnderlying();              // Strategy's underlying asset doesn't match
error InvalidDebtRatio();                       // Debt ratio exceeds maximum allowed
error InvalidMinDebtPerHarvest();               // Invalid minimum debt per harvest value
error InvalidPerformanceFee();                  // Performance fee exceeds maximum allowed
error InvalidManagementFee();                   // Management fee exceeds maximum allowed
error StrategyDebtRatioAlreadyZero();          // Strategy's debt ratio is already zero
error InvalidQueueOrder();                      // Invalid withdrawal queue ordering
error VaultDepositLimitExceeded();             // Deposit would exceed vault's limit
error InvalidZeroAmount();                      // Zero amount provided where not allowed
error InvalidZeroShares();                      // Zero shares amount where not allowed
error LossGreaterThanStrategyTotalDebt();      // Reported loss exceeds strategy's total debt
error InvalidReportedGainAndDebtPayment();      // Invalid gain and debt payment reported
error FeesAlreadyAssesed();                    // Fees have already been assessed
```

## Events

### Strategy Management Events

```solidity
event StrategyAdded(
    address indexed newStrategy,
    uint16 strategyDebtRatio,
    uint128 strategyMaxDebtPerHarvest,
    uint128 strategyMinDebtPerHarvest,
    uint16 strategyPerformanceFee
);

event StrategyRemoved(address indexed strategy);
event StrategyRevoked(address indexed strategy);
event StrategyExited(address indexed strategy, uint256 withdrawn);

event StrategyUpdated(
    address indexed strategy,
    uint16 newDebtRatio,
    uint128 newMaxDebtPerHarvest,
    uint128 newMinDebtPerHarvest,
    uint16 newPerformanceFee
);

event StrategyReported(
    address indexed strategy,
    uint256 unrealizedGain,
    uint256 loss,
    uint256 debtPayment,
    uint128 strategyTotalUnrealizedGain,
    uint128 strategyTotalLoss,
    uint128 strategyTotalDebt,
    uint256 credit,
    uint16 strategyDebtRatio
);
```

### Configuration Events

```solidity
event EmergencyShutdownUpdated(bool emergencyShutdown);
event AutopilotEnabled(bool isEnabled);
event WithdrawalQueueUpdated(address[20] withdrawalQueue);
event PerformanceFeeUpdated(uint16 newPerformanceFee);
event ManagementFeeUpdated(uint256 newManagementFee);
event DepositLimitUpdated(uint256 newDepositLimit);
event TreasuryUpdated(address treasury);
```

### Operation Events

```solidity
event WithdrawFromStrategy(address indexed strategy, uint128 strategyTotalDebt, uint128 loss);
event FeesReported(uint256 managementFee, uint16 performanceFee, uint256 strategistFee, uint256 duration);
event ForceHarvestFailed(address indexed strategy, bytes reason);
```

## State Variables

```solidity
bool public emergencyShutdown;                  // Emergency shutdown state
bool public autoPilotEnabled;                   // Automated harvesting state
uint8 private immutable _decimals;              // Underlying token decimals
uint8 public nexHarvestStrategyIndex;           // Next strategy index to harvest
uint256 public depositLimit;                    // Maximum total assets limit
uint256 public debtRatio;                       // Total debt ratio across strategies (in BPS)
uint256 public totalIdle;                       // Tokens held in vault
uint256 public totalDebt;                       // Total tokens allocated to strategies
uint256 public lastReport;                      // Timestamp of last strategy report
uint256 public performanceFee;                  // Performance fee rate (in BPS)
uint256 public managementFee;                   // Management fee rate (in BPS)
address public treasury;                        // Fee recipient address

mapping(address => StrategyData) public strategies;  // Strategy data mapping
address[MAXIMUM_STRATEGIES] public withdrawalQueue;   // Strategy withdrawal order

string private _name;                           // Vault shares token name
string private _symbol;                         // Vault shares token symbol
address private immutable _underlyingAsset;     // Underlying asset address
```

## Functions

### Basic View Functions

### name

```solidity
function name() public view override returns (string memory)
```

Returns the name of the vault shares token.

Returns:

* The token name

### symbol

```solidity
function symbol() public view override returns (string memory)
```

Returns the symbol of the vault shares token.

Returns:

* The token symbol

### asset

```solidity
function asset() public view override returns (address)
```

Returns the address of the underlying token that the vault accepts.

Returns:

* The underlying asset address

### totalAssets

```solidity
function totalAssets() public view override returns (uint256)
```

Returns total assets managed by vault, including idle funds and assets deployed in strategies.

Returns:

* The total assets under management

### totalDeposits

```solidity
function totalDeposits() public view returns (uint256)
```

Returns the sum of idle assets and debt allocated to strategies.

Returns:

* The total accounted assets

### sharePrice

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

Returns the current price of one vault share regarding the underlying asset.

Returns:

* The current share price

### Asset/Share Conversion Functions

### convertToShares

```solidity
function convertToShares(uint256 assets) public view override returns (uint256)
```

Calculates how many shares would be minted for a given amount of assets.

Parameters:

* `assets`: Amount of underlying assets to convert

Returns:

* The equivalent amount of shares

### convertToAssets

```solidity
function convertToAssets(uint256 shares) public view override returns (uint256)
```

Calculates how many underlying assets a given amount of shares represents.

Parameters:

* `shares`: Amount of shares to convert

Returns:

* The equivalent amount of assets

### Deposit Limit Functions

### maxDeposit

```solidity
function maxDeposit(address to) public view override returns (uint256)
```

Calculates the maximum amount of assets that can be deposited.

Parameters:

* `to`: Address that would receive the shares (unused in calculation)

Returns:

* Maximum deposit amount allowed

### maxMint

```solidity
function maxMint(address to) public view override returns (uint256)
```

Calculates the maximum amount of shares that can be minted.

Parameters:

* `to`: Address that would receive the shares (unused in calculation)

Returns:

* Maximum shares that can be minted

### maxWithdraw

```solidity
function maxWithdraw(address owner) public view override returns (uint256)
```

Returns the maximum amount of assets that an address can withdraw.

Parameters:

* `owner`: Address of the shares owner

Returns:

* Maximum assets that can be withdrawn

### Preview Functions

### previewMint

```solidity
function previewMint(uint256 shares) public view override returns (uint256)
```

Simulates the amount of assets needed to mint a specific amount of shares.

Parameters:

* `shares`: The amount of shares to mint

Returns:

* The amount of assets required

### previewWithdraw

```solidity
function previewWithdraw(uint256 assets) public view override returns (uint256)
```

Simulates the amount of shares needed to withdraw a specific amount of assets.

Parameters:

* `assets`: The amount of assets to withdraw

Returns:

* The amount of shares required

### previewRedeem

```solidity
function previewRedeem(uint256 shares) public view override returns (uint256)
```

Simulates the amount of assets that would be received when redeeming shares.

Parameters:

* `shares`: The amount of shares to redeem

Returns:

* The amount of assets that would be received

### Strategy View Functions

### creditAvailable

```solidity
function creditAvailable(address strategy) external view returns (uint256)
```

Returns the amount of additional funds a strategy can borrow from the vault.

Parameters:

* `strategy`: The strategy address to check

Returns:

* The amount of credit available

### debtOutstanding

```solidity
function debtOutstanding(address strategy) external view returns (uint256)
```

Returns the amount of debt that a strategy needs to repay to the vault.

Parameters:

* `strategy`: The strategy address to check

Returns:

* The amount of outstanding debt

### getStrategyTotalDebt

```solidity
function getStrategyTotalDebt(address strategy) external view returns (uint256)
```

Returns the total debt allocated to a strategy.

Parameters:

* `strategy`: The strategy address to check

Returns:

* The strategy's total debt

### Deposit Functions

### deposit

```solidity
function deposit(uint256 assets, address receiver) public returns (uint256 shares)
```

Deposits underlying assets into the vault and mints shares to the receiver. Only possible when vault is not in emergency shutdown.

Parameters:

* `assets`: Amount of underlying assets to deposit
* `receiver`: Address to receive the minted shares

Returns:

* Amount of shares minted

### depositWithPermit

```solidity
function depositWithPermit(
    address owner,
    uint256 assets,
    uint256 deadline,
    uint8 v,
    bytes32 r,
    bytes32 s,
    address receiver
) public returns (uint256 shares)
```

Deposits assets using an EIP-2612 permit for approval. Prevents extra approve transaction.

Parameters:

* `owner`: Owner of the assets
* `assets`: Amount of assets to deposit
* `deadline`: Timestamp until which the permit is valid
* `v`: Signature parameter
* `r`: Signature parameter
* `s`: Signature parameter
* `receiver`: Address to receive the shares

Returns:

* Amount of shares minted

### mint

```solidity
function mint(uint256 shares, address receiver) public returns (uint256 assets)
```

Mints an exact amount of shares by depositing the necessary amount of assets.

Parameters:

* `shares`: Amount of shares to mint
* `receiver`: Address to receive the shares

Returns:

* Amount of assets deposited

### mintWithPermit

```solidity
function mintWithPermit(
    address owner,
    uint256 shares,
    uint256 deadline,
    uint8 v,
    bytes32 r,
    bytes32 s,
    address receiver
) public returns (uint256 assets)
```

Mints exact shares using an EIP-2612 permit for approval.

Parameters:

* `owner`: Owner of the assets
* `shares`: Amount of shares to mint
* `deadline`: Timestamp until which the permit is valid
* `v`: Signature parameter
* `r`: Signature parameter
* `s`: Signature parameter
* `receiver`: Address to receive the shares

Returns:

* Amount of assets deposited

### Withdrawal Functions

### withdraw

```solidity
function withdraw(
    uint256 assets,
    address receiver,
    address owner
) public returns (uint256 shares)
```

Withdraws exact assets by burning the required amount of shares.

Parameters:

* `assets`: Amount of assets to withdraw
* `receiver`: Address to receive the assets
* `owner`: Owner of the shares

Returns:

* Amount of shares burned

### redeem

```solidity
function redeem(
    uint256 shares,
    address receiver,
    address owner
) public returns (uint256 assets)
```

Burns exact shares for underlying assets.

Parameters:

* `shares`: Amount of shares to redeem
* `receiver`: Address to receive the assets
* `owner`: Owner of the shares

Returns:

* Amount of assets withdrawn

### Strategy Management Functions

### addStrategy

```solidity
function addStrategy(
    address strategy,
    uint256 debtRatio,
    uint256 maxDebtPerHarvest,
    uint256 minDebtPerHarvest,
    uint256 performanceFee
) external
```

Adds a new strategy to the vault. Can only be called by admin and not during emergency shutdown.

Parameters:

* `strategy`: Address of the strategy to add
* `debtRatio`: Percentage of vault's total assets that strategy can manage (in BPS)
* `maxDebtPerHarvest`: Maximum debt the strategy can take on in a single harvest
* `minDebtPerHarvest`: Minimum debt the strategy should take in a single harvest
* `performanceFee`: Performance fee for the strategy (in BPS)

### removeStrategy

```solidity
function removeStrategy(address strategy) external
```

Removes a strategy from the vault's withdrawal queue. Can only be called by admin and not during emergency shutdown.

Parameters:

* `strategy`: Address of the strategy to remove

### revokeStrategy

```solidity
function revokeStrategy(address strategy) external
```

Revokes a strategy by setting its debt ratio to 0 and preventing future deposits. Can only be called by admin.

Parameters:

* `strategy`: Address of the strategy to revoke

### exitStrategy

```solidity
function exitStrategy(address strategy) external
```

Fully exits a strategy by liquidating all positions and removing it from the withdrawal queue. Can only be called by admin.

Parameters:

* `strategy`: Address of the strategy to exit

### updateStrategyData

```solidity
function updateStrategyData(
    address strategy,
    uint256 newDebtRatio,
    uint256 newMaxDebtPerHarvest,
    uint256 newMinDebtPerHarvest,
    uint256 newPerformanceFee
) external
```

Updates a strategy's configuration parameters. Can only be called by admin.

Parameters:

* `strategy`: Address of the strategy to update
* `newDebtRatio`: New debt ratio (in BPS)
* `newMaxDebtPerHarvest`: New maximum debt per harvest
* `newMinDebtPerHarvest`: New minimum debt per harvest
* `newPerformanceFee`: New performance fee (in BPS)

### Reporting Functions

### report

```solidity
function report(
    uint128 realizedGain,
    uint128 unrealizedGain,
    uint128 loss,
    uint128 debtPayment,
    address managementFeeReceiver
) external returns (uint256)
```

Reports strategy performance and handles profit/loss accounting. Can only be called by strategies.

Parameters:

* `realizedGain`: Realized profit
* `unrealizedGain`: Unrealized profit
* `loss`: Amount of losses
* `debtPayment`: Amount of debt being repaid
* `managementFeeReceiver`: Address to receive management fees

Returns:

* Updated debt outstanding

### Configuration Functions

### setWithdrawalQueue

```solidity
function setWithdrawalQueue(address[MAXIMUM_STRATEGIES] calldata queue) external
```

Sets the order of strategies for withdrawals. Can only be called by admin.

Parameters:

* `queue`: Array of strategy addresses in withdrawal order

### setPerformanceFee

```solidity
function setPerformanceFee(uint256 _performanceFee) external
```

Updates the vault's performance fee. Can only be called by admin.

Parameters:

* `_performanceFee`: New performance fee (in BPS)

### setManagementFee

```solidity
function setManagementFee(uint256 _managementFee) external
```

Updates the vault's management fee. Can only be called by admin.

Parameters:

* `_managementFee`: New management fee (in BPS)

### setDepositLimit

```solidity
function setDepositLimit(uint256 _depositLimit) external
```

Sets the maximum total assets the vault can accept. Can only be called by admin.

Parameters:

* `_depositLimit`: New deposit limit

### setEmergencyShutdown

```solidity
function setEmergencyShutdown(bool _emergencyShutdown) external
```

Enables/disables emergency shutdown mode. Can only be called by emergency admin.

Parameters:

* `_emergencyShutdown`: True to enable shutdown, false to disable

### setTreasury

```solidity
function setTreasury(address _treasury) external
```

Updates the treasury address that receives fees. Can only be called by admin.

Parameters:

* `_treasury`: New treasury address

### setAutopilotEnabled

```solidity
function setAutopilotEnabled(bool _autoPilotEnabled) external
```

Enables/disables automated strategy harvesting. Can only be called by admin.

Parameters:

* `_autoPilotEnabled`: True to enable autopilot, false to disable

### setAutoPilot

```solidity
function setAutoPilot(bool _autoPilot) external
```

Sets autopilot mode for a specific strategy. Can only be called by strategies.

Parameters:

* `_autoPilot`: True to enable autopilot for the strategy

### Internal Functions

### \_forceOneHarvest

```solidity
function _forceOneHarvest(address harvester) internal returns (address strategy, bool success, bytes memory reason)
```

Forces a harvest of the next strategy in autopilot mode.

Parameters:

* `harvester`: Address that will receive extra shares for harvesting

Returns:

* `strategy`: Address of the harvested strategy
* `success`: Whether the harvest was successful
* `reason`: Error reason if harvest failed

### \_reportLoss

```solidity
function _reportLoss(address strategy, uint256 loss) internal
```

Handles strategy loss reporting by adjusting debt ratios and total debt.

Parameters:

* `strategy`: Strategy reporting the loss
* `loss`: Amount of loss to report

### \_assessFees

```solidity
function _assessFees(address strategy, uint256 gain, address managementFeeReceiver) internal returns (uint256)
```

Calculates and distributes performance, management, and strategist fees.

Parameters:

* `strategy`: Strategy the fees are being assessed for
* `gain`: Amount of profit to assess fees on
* `managementFeeReceiver`: Address to receive management fees

Returns:

* Total amount of fees assessed

### \_creditAvailable

```solidity
function _creditAvailable(address strategy) internal view returns (uint256)
```

Calculates available credit line for a strategy.

Parameters:

* `strategy`: Strategy to check credit for

Returns:

* Amount of credit available

### \_computeDebtLimit

```solidity
function _computeDebtLimit(uint256 _debtRatio, uint256 totalAssets_) internal pure returns (uint256 debtLimit)
```

Calculates maximum debt limit based on debt ratio and total assets.

Parameters:

* `_debtRatio`: Debt ratio to use (in BPS)
* `totalAssets_`: Total assets to base calculation on

Returns:

* Calculated debt limit

### \_debtOutstanding

```solidity
function _debtOutstanding(address strategy) internal view returns (uint256)
```

Calculates how much debt a strategy needs to pay back.

Parameters:

* `strategy`: Strategy to check debt for

Returns:

* Amount of outstanding debt

### \_organizeWithdrawalQueue

```solidity
function _organizeWithdrawalQueue() internal
```

Reorganizes withdrawal queue by removing gaps and maintaining relative order.

### \_revokeStrategy

```solidity
function _revokeStrategy(address strategy, uint256 strategyDebtRatio) internal
```

Internal function to revoke a strategy and update debt ratios.

Parameters:

* `strategy`: Strategy to revoke
* `strategyDebtRatio`: Current debt ratio of the strategy

### \_issueSharesForAmount

```solidity
function _issueSharesForAmount(address to, uint256 amount) internal returns (uint256 shares)
```

Calculates and mints shares for a given amount of assets.

Parameters:

* `to`: Address to receive shares
* `amount`: Amount of assets to convert to shares

Returns:

* Amount of shares minted

### Helper Functions

### *eitherIsZero*

```solidity
function _eitherIsZero_(uint256 a, uint256 b) internal pure returns (bool)
```

Checks if either of two values is zero.

Parameters:

* `a`: First value to check
* `b`: Second value to check

Returns:

* True if either value is zero

### *inc*

```solidity
function _inc_(uint256 x) internal pure returns (uint256)
```

Returns value plus one.

Parameters:

* `x`: Value to increment

Returns:

* Incremented value

### \_sub0

```solidity
function _sub0(uint256 a, uint256 b) internal pure returns (uint256)
```

Safely subtracts b from a, returning 0 if result would be negative.

Parameters:

* `a`: Value to subtract from
* `b`: Value to subtract

Returns:

* Result of subtraction or 0

### ERC4626 Override Functions

### \_underlyingDecimals

```solidity
function _underlyingDecimals() internal view override returns (uint8)
```

Returns decimals of the underlying token.

Returns:

* Number of decimals

### \_decimalsOffset

```solidity
function _decimalsOffset() internal pure override returns (uint8)
```

Returns decimal offset used to prevent inflation attacks.

Returns:

* Decimal offset value (6)

### \_totalAssets

```solidity
function _totalAssets() internal view returns (uint256)
```

Calculates total assets including idle funds and strategy positions.

Returns:

* Total assets under management

### \_totalDeposits

```solidity
function _totalDeposits() internal view returns (uint256)
```

Returns sum of idle assets and total debt.

Returns:

* Total deposited assets

### \_deposit

```solidity
function _deposit(address by, address to, uint256 assets, uint256 shares) internal override
```

Internal deposit implementation with additional checks.

Parameters:

* `by`: Address depositing assets
* `to`: Address receiving shares
* `assets`: Amount of assets being deposited
* `shares`: Amount of shares to mint

### \_withdraw

```solidity
function _withdraw(address by, address to, address owner, uint256 assets) private returns (uint256 shares)
```

Internal withdraw implementation handling liquidations.

Parameters:

* `by`: Address initiating withdrawal
* `to`: Address receiving assets
* `owner`: Owner of the shares
* `assets`: Amount of assets to withdraw

Returns:

* Amount of shares burned

### \_redeem

```solidity
function _redeem(address by, address to, address owner, uint256 shares) private returns (uint256 assets)
```

Internal redeem implementation handling liquidations.

Parameters:

* `by`: Address initiating redemption
* `to`: Address receiving assets
* `owner`: Owner of the shares
* `shares`: Amount of shares to redeem

Returns:

* Amount of assets returned
