# LogarithmVault

**Inherits:** Initializable, PausableUpgradeable, ManagedVault

**Author:** Logarithm Labs

The Logarithm Vault supplies depositor funds to a single connected strategy, with depositors receiving shares proportional to their contributions and paying entry fees to cover the strategy’s execution costs. Vault tokens are yield-bearing and can be redeemed at any time, enabling depositors to withdraw their initial investment plus any generated yield, while incurring exit fees to cover strategy-related costs. When idle assets are available in the vault, redemptions may proceed synchronously; otherwise, they occur asynchronously as funds are withdrawn from the strategy, involving interactions with asynchronous protocols like GMX and cross-chain systems such as HyperLiquid.

*The withdrawable assets and redeemable shares are determined by the `maxRequestWithdraw` and `maxRequestRedeem` functions and are executed via `requestWithdraw` and `requestRedeem`. These functions return a unique withdrawal key that can be used to check the status and claimability of the withdraw request. Standard ERC4626-compliant functions — `maxWithdraw`, `maxRedeem`, `withdraw`, and `redeem` — remain available but operate exclusively with idle assets within the vault. LogarithmVault is an ERC4626-compliant, upgradeable vault with asynchronous redemption functionality, deployed through a beacon proxy pattern.*

### State Variables

#### LogarithmVaultStorageLocation

```solidity
bytes32 private constant LogarithmVaultStorageLocation =
    0xa6bd21c53796194571f225e7dc34d762d966d8495887cd7c53f8cab2693cb800;
```

### Functions

#### \_getLogarithmVaultStorage

```solidity
function _getLogarithmVaultStorage() private pure returns (LogarithmVaultStorage storage $);
```

#### onlySecurityManager

*Reverts if the caller is not a security manager.*

```solidity
modifier onlySecurityManager();
```

#### initialize

```solidity
function initialize(
    address owner_,
    address asset_,
    address priorityProvider_,
    uint256 entryCost_,
    uint256 exitCost_,
    string calldata name_,
    string calldata symbol_
) external initializer;
```

#### \_setEntryCost

```solidity
function _setEntryCost(uint256 value) internal;
```

#### \_setExitCost

```solidity
function _setExitCost(uint256 value) internal;
```

#### \_setPriorityProvider

```solidity
function _setPriorityProvider(address newProvider) internal;
```

#### setSecurityManager

Configures the security manager.

```solidity
function setSecurityManager(address account) external onlyOwner;
```

**Parameters**

| Name      | Type      | Description                                                                                     |
| --------- | --------- | ----------------------------------------------------------------------------------------------- |
| `account` | `address` | The address of new security manager. A zero address means disabling security manager functions. |

#### setStrategy

Configures the strategy. Note:

* Approve new strategy to manage asset of this vault infinitely.
* If there is an old strategy, revoke its asset approval after stopping the strategy.

```solidity
function setStrategy(address _strategy) external onlyOwner;
```

#### setEntryCost

Configures new entry cost setting.

```solidity
function setEntryCost(uint256 newEntryCost) external onlyOwner;
```

#### setExitCost

Configures new exit cost setting.

```solidity
function setExitCost(uint256 newExitCost) external onlyOwner;
```

#### setPriorityProvider

Configures new priority provider.

```solidity
function setPriorityProvider(address newProvider) external onlyOwner;
```

#### shutdown

Shutdown vault, where all deposit/mint are disabled while withdraw/redeem are still available.

```solidity
function shutdown() external onlyOwner;
```

#### pause

Pauses Vault temporarily so that deposit and withdraw functions are disabled. This function is callable only by the security manager and is used if some unexpected behaviors from external protocols are spotted by the security manager.

```solidity
function pause(bool stopStrategy) external onlySecurityManager whenNotPaused;
```

**Parameters**

| Name           | Type   | Description                                               |
| -------------- | ------ | --------------------------------------------------------- |
| `stopStrategy` | `bool` | True means stopping strategy, otherwise pausing strategy. |

#### unpause

*Unpauses Vault while unpausing the connected strategy. This function is callable only by the security manager.*

```solidity
function unpause() external onlySecurityManager whenPaused;
```

#### maxRequestWithdraw

Returns the maximum amount of the underlying asset that can be requested to withdraw from the owner balance in the Vault, through a requestWithdraw call.

```solidity
function maxRequestWithdraw(address owner) public view returns (uint256);
```

#### maxRequestRedeem

Returns the maximum amount of Vault shares that can be requested to redeem from the owner balance in the Vault, through a requestRedeem call.

```solidity
function maxRequestRedeem(address owner) public view returns (uint256);
```

#### requestWithdraw

Requests to withdraw assets and returns a unique withdraw key if the requested asset amount is bigger than the idle assets. If idle assets are available in the Vault, they are withdrawn synchronously within the `requestWithdraw` call, while any shortfall amount remains pending for execution by the system.

*Burns shares from owner and sends exactly assets of underlying tokens to receiver if the idle assets is enough. If the idle assets is not enough, creates a withdraw request with the shortfall assets while sending the idle assets to receiver.*

```solidity
function requestWithdraw(uint256 assets, address receiver, address owner) public virtual returns (bytes32);
```

**Returns**

| Name     | Type      | Description                                          |
| -------- | --------- | ---------------------------------------------------- |
| `<none>` | `bytes32` | The withdraw key that is used in the claim function. |

#### requestRedeem

Requests to redeem shares and returns a unique withdraw key if the derived asset amount is bigger than the idle assets. If idle assets are available in the Vault, they are withdrawn synchronously within the `requestWithdraw` call, while any shortfall amount remains pending for execution by the system.

*Burns exactly shares from owner and sends assets of underlying tokens to receiver if the idle assets is enough, If the idle assets is not enough, creates a withdraw request with the shortfall assets while sending the idle assets to receiver.*

```solidity
function requestRedeem(uint256 shares, address receiver, address owner) public virtual returns (bytes32);
```

**Returns**

| Name     | Type      | Description                                          |
| -------- | --------- | ---------------------------------------------------- |
| `<none>` | `bytes32` | The withdraw key that is used in the claim function. |

#### \_requestWithdraw

*requestWithdraw/requestRedeem common workflow.*

```solidity
function _requestWithdraw(
    address caller,
    address receiver,
    address owner,
    uint256 assetsToRequest,
    uint256 sharesToRequest
) internal virtual returns (bytes32);
```

#### processPendingWithdrawRequests

Processes pending withdraw requests with idle assets.

*This is a decentralized function that can be called by anyone.*

```solidity
function processPendingWithdrawRequests() public returns (uint256);
```

**Returns**

| Name     | Type      | Description                                           |
| -------- | --------- | ----------------------------------------------------- |
| `<none>` | `uint256` | The assets used to process pending withdraw requests. |

#### claim

Claims a withdraw request if it is executed.

```solidity
function claim(bytes32 withdrawRequestKey) public virtual returns (uint256);
```

**Parameters**

| Name                 | Type      | Description                                                          |
| -------------------- | --------- | -------------------------------------------------------------------- |
| `withdrawRequestKey` | `bytes32` | The withdraw key that was returned by requestWithdraw/requestRedeem. |

#### isClaimable

Tells if the withdraw request is claimable or not.

```solidity
function isClaimable(bytes32 withdrawRequestKey) external view returns (bool);
```

**Parameters**

| Name                 | Type      | Description                                                          |
| -------------------- | --------- | -------------------------------------------------------------------- |
| `withdrawRequestKey` | `bytes32` | The withdraw key that was returned by requestWithdraw/requestRedeem. |

#### isPrioritized

Tells if the owner is prioritized to withdraw.

```solidity
function isPrioritized(address owner) public view returns (bool);
```

#### idleAssets

The underlying asset amount in this vault that is free to withdraw or utilize.

```solidity
function idleAssets() public view returns (uint256);
```

#### totalPendingWithdraw

The underlying asset amount requested to withdraw, that is not executed yet.

```solidity
function totalPendingWithdraw() public view returns (uint256);
```

#### getWithdrawKey

*Derives a unique withdraw key based on the user’s address and his/her nonce.*

```solidity
function getWithdrawKey(address user, uint256 nonce) public view returns (bytes32);
```

#### totalAssets

*See {IERC4626-totalAssets}.*

```solidity
function totalAssets() public view virtual override returns (uint256 assets);
```

#### previewDeposit

*See {IERC4626-previewDeposit}.*

```solidity
function previewDeposit(uint256 assets) public view virtual override returns (uint256);
```

#### previewMint

*See {IERC4626-previewMint}.*

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

#### previewWithdraw

*See {IERC4626-previewWithdraw}.*

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

#### previewRedeem

*See {IERC4626-previewRedeem}.*

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

#### maxDeposit

*See {IERC4626-maxDeposit}.*

```solidity
function maxDeposit(address receiver) public view virtual override returns (uint256);
```

#### maxMint

*See {IERC4626-maxMint}.*

```solidity
function maxMint(address receiver) public view virtual override returns (uint256);
```

#### maxWithdraw

*This is limited by the idle assets.*

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

#### maxRedeem

*This is limited by the idle assets.*

```solidity
function maxRedeem(address owner) public view virtual override returns (uint256);
```

#### \_deposit

*If there are pending withdraw requests, the deposited assets is used to process them. And disables harvesting of the performance fee as a core logarithm vault doesn’t have the functionality.*

```solidity
function _deposit(address caller, address receiver, uint256 assets, uint256 shares) internal virtual override;
```

#### \_withdraw

*Disables harvesting of the performance fee as a core logarithm vault doesn’t have the functionality.*

```solidity
function _withdraw(address caller, address receiver, address owner, uint256 assets, uint256 shares) internal override;
```

#### \_calcProcessedAssets

*Calculates the processed withdrawal assets.*

```solidity
function _calcProcessedAssets(
    uint256 _idleAssets,
    uint256 _processedWithdrawAssets,
    uint256 _accRequestedWithdrawAssets
) internal pure returns (uint256 remainingAssets, uint256 processedAssets);
```

**Parameters**

| Name                          | Type      | Description                                                 |
| ----------------------------- | --------- | ----------------------------------------------------------- |
| `_idleAssets`                 | `uint256` | The idle assets available for processing withdraw requests. |
| `_processedWithdrawAssets`    | `uint256` | The value of processedWithdrawAssets storage variable.      |
| `_accRequestedWithdrawAssets` | `uint256` | The value of accRequestedWithdrawAssets storage variable.   |

**Returns**

| Name              | Type      | Description                                 |
| ----------------- | --------- | ------------------------------------------- |
| `remainingAssets` | `uint256` | The remaining asset amount after processing |
| `processedAssets` | `uint256` | The processed asset amount                  |

#### \_isWithdrawRequestExecuted

*Executable state of withdraw request*

```solidity
function _isWithdrawRequestExecuted(bool isPrioritizedAccount, uint256 accRequestedWithdrawAssetsOfRequest)
    internal
    view
    returns (bool isExecuted, bool isLast);
```

**Parameters**

| Name                                  | Type      | Description                                                      |
| ------------------------------------- | --------- | ---------------------------------------------------------------- |
| `isPrioritizedAccount`                | `bool`    | Tells if account is prioritized for withdrawal                   |
| `accRequestedWithdrawAssetsOfRequest` | `uint256` | The accRequestedWithdrawAssets storage value of withdraw request |

**Returns**

| Name         | Type   | Description                                |
| ------------ | ------ | ------------------------------------------ |
| `isExecuted` | `bool` | Tells whether a request is executed or not |
| `isLast`     | `bool` | Tells whether a request is last or not     |

#### \_useNonce

*Uses nonce of the specified user and increase it*

```solidity
function _useNonce(address user) internal returns (uint256);
```

#### \_costOnRaw

*Calculates the cost that should be added to an amount `assets` that does not include cost. Used in IERC4626-mint and {IERC4626-withdraw} operations.*

```solidity
function _costOnRaw(uint256 assets, uint256 costRate) private pure returns (uint256);
```

#### \_costOnTotal

*Calculates the cost part of an amount `assets` that already includes cost. Used in IERC4626-deposit and {IERC4626-redeem} operations.*

```solidity
function _costOnTotal(uint256 assets, uint256 costRate) private pure returns (uint256);
```

#### strategy

The address of strategy that uses the underlying asset of this vault.

```solidity
function strategy() public view returns (address);
```

#### priorityProvider

The priority provider address which provides the prioritized accounts. For example, the addresses of logarithm meta vaults are prioritized to withdraw. Prioritizing of withdraw means that their withdraw requests are processed before the other normal withdraw requests.

```solidity
function priorityProvider() public view returns (address);
```

#### entryCost

The entry cost percent that is charged when depositing.

*Denominated in 18 decimals.*

```solidity
function entryCost() public view returns (uint256);
```

#### exitCost

The exit cost percent that is charged when withdrawing.

*Denominated in 18 decimals.*

```solidity
function exitCost() public view returns (uint256);
```

#### assetsToClaim

The underlying asset amount that is in Vault and reserved to claim for the executed withdraw requests.

```solidity
function assetsToClaim() public view returns (uint256);
```

#### accRequestedWithdrawAssets

*The accumulated underlying asset amount requested to withdraw by the normal users.*

```solidity
function accRequestedWithdrawAssets() public view returns (uint256);
```

#### processedWithdrawAssets

*The accumulated underlying asset amount processed for the normal withdraw requests.*

```solidity
function processedWithdrawAssets() public view returns (uint256);
```

#### prioritizedAccRequestedWithdrawAssets

*The accumulated underlying asset amount requested to withdraw by the prioritized users.*

```solidity
function prioritizedAccRequestedWithdrawAssets() public view returns (uint256);
```

#### prioritizedProcessedWithdrawAssets

*The accumulated underlying asset amount processed for the prioritized withdraw requests.*

```solidity
function prioritizedProcessedWithdrawAssets() public view returns (uint256);
```

#### withdrawRequests

*Returns the state of a withdraw request for the withdrawKey.*

```solidity
function withdrawRequests(bytes32 withdrawKey) public view returns (WithdrawRequest memory);
```

#### nonces

*Returns a nonce of a user that are reserved to generate the next withdraw key.*

```solidity
function nonces(address user) public view returns (uint256);
```

#### securityManager

The address of security manager who is responsible for pausing/unpausing vault.

```solidity
function securityManager() public view returns (address);
```

#### isShutdown

When this vault is shutdown, only withdrawals are available. It can’t be reverted.

```solidity
function isShutdown() public view returns (bool);
```

### Events

#### WithdrawRequested

*Emitted when a new withdraw/redeem request is created.*

```solidity
event WithdrawRequested(
    address indexed caller,
    address indexed receiver,
    address indexed owner,
    bytes32 withdrawKey,
    uint256 assets,
    uint256 shares
);
```

**Parameters**

| Name          | Type      | Description                                             |
| ------------- | --------- | ------------------------------------------------------- |
| `caller`      | `address` | The address of withdraw requestor.                      |
| `receiver`    | `address` | The address who receives the withdraw assets.           |
| `owner`       | `address` | The address of owner who was requested to withdraw.     |
| `withdrawKey` | `bytes32` | The bytes32 value that identifies the withdraw request. |
| `assets`      | `uint256` | The asset amount that is requested to withdraw.         |
| `shares`      | `uint256` | The share amount that is burnt.                         |

#### Claimed

*Emitted when a withdraw request gets claimed.*

```solidity
event Claimed(address indexed claimer, bytes32 withdrawKey, uint256 assets);
```

**Parameters**

| Name          | Type      | Description                                              |
| ------------- | --------- | -------------------------------------------------------- |
| `claimer`     | `address` | The address who claimed the withdraw request.            |
| `withdrawKey` | `bytes32` | The bytes32 withdraw key identifying a withdraw request. |
| `assets`      | `uint256` | The asset amount that is claimed.                        |

#### Shutdown

*Emitted when this vault get shutdown.*

```solidity
event Shutdown(address account);
```

**Parameters**

| Name      | Type      | Description                          |
| --------- | --------- | ------------------------------------ |
| `account` | `address` | The address who shutdown this vault. |

#### SecurityManagerUpdated

*Emitted when a new security manager is set.*

```solidity
event SecurityManagerUpdated(address account, address newManager);
```

**Parameters**

| Name         | Type      | Description                                   |
| ------------ | --------- | --------------------------------------------- |
| `account`    | `address` | The address who changed the security manager. |
| `newManager` | `address` | The address of new security manager.          |

#### StrategyUpdated

*Emitted when a new strategy is set.*

```solidity
event StrategyUpdated(address account, address newStrategy);
```

**Parameters**

| Name          | Type      | Description                                    |
| ------------- | --------- | ---------------------------------------------- |
| `account`     | `address` | The address who changed strategy to a new one. |
| `newStrategy` | `address` | The address of a new strategy.                 |

#### EntryCostUpdated

*Emitted when the entry cost configuration is changed.*

```solidity
event EntryCostUpdated(address account, uint256 newEntryCost);
```

**Parameters**

| Name           | Type      | Description                                           |
| -------------- | --------- | ----------------------------------------------------- |
| `account`      | `address` | The address who changed the entry cost configuration. |
| `newEntryCost` | `uint256` | The value of the new entry cost configuration.        |

#### ExitCostUpdated

*Emitted when the exit cost configuration is changed.*

```solidity
event ExitCostUpdated(address account, uint256 newExitCost);
```

**Parameters**

| Name          | Type      | Description                                          |
| ------------- | --------- | ---------------------------------------------------- |
| `account`     | `address` | The address who changed the exit cost configuration. |
| `newExitCost` | `uint256` | The value of the new exit cost configuration.        |

#### PriorityProviderUpdated

*Emitted when the priority provider address is changed.*

```solidity
event PriorityProviderUpdated(address account, address newPriorityProvider);
```

**Parameters**

| Name                  | Type      | Description                                    |
| --------------------- | --------- | ---------------------------------------------- |
| `account`             | `address` | The address who changed the priority provider. |
| `newPriorityProvider` | `address` | The address of new priority provider.          |

### Structs

#### WithdrawRequest

A struct describing an user’s withdraw request.

```solidity
struct WithdrawRequest {
    uint256 requestedAssets;
    uint256 accRequestedWithdrawAssets;
    uint256 requestTimestamp;
    address owner;
    address receiver;
    bool isClaimed;
}
```

#### LogarithmVaultStorage

```solidity
struct LogarithmVaultStorage {
    address strategy;
    uint256 entryCost;
    uint256 exitCost;
    uint256 assetsToClaim;
    uint256 accRequestedWithdrawAssets;
    uint256 processedWithdrawAssets;
    mapping(address => uint256) nonces;
    mapping(bytes32 => WithdrawRequest) withdrawRequests;
    address priorityProvider;
    uint256 prioritizedAccRequestedWithdrawAssets;
    uint256 prioritizedProcessedWithdrawAssets;
    address securityManager;
    bool shutdown;
}
```
