AlephVault

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "src/AlephVault.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;
/*
  ______   __                      __       
 /      \ /  |                    /  |      
/$$$$$$  |$$ |  ______    ______  $$ |____  
$$ |__$$ |$$ | /      \  /      \ $$      \ 
$$    $$ |$$ |/$$$$$$  |/$$$$$$  |$$$$$$$  |
$$$$$$$$ |$$ |$$    $$ |$$ |  $$ |$$ |  $$ |
$$ |  $$ |$$ |$$$$$$$$/ $$ |__$$ |$$ |  $$ |
$$ |  $$ |$$ |$$       |$$    $$/ $$ |  $$ |
$$/   $$/ $$/  $$$$$$$/ $$$$$$$/  $$/   $$/ 
                        $$ |                
                        $$ |                
                        $$/                 
*/

import {Time} from "openzeppelin-contracts/contracts/utils/types/Time.sol";
import {IAccountant} from "@aleph-vault/interfaces/IAccountant.sol";
import {IAlephVault} from "@aleph-vault/interfaces/IAlephVault.sol";
import {IAlephVaultDeposit} from "@aleph-vault/interfaces/IAlephVaultDeposit.sol";
import {IAlephVaultRedeem} from "@aleph-vault/interfaces/IAlephVaultRedeem.sol";
import {IAlephVaultSettlement} from "@aleph-vault/interfaces/IAlephVaultSettlement.sol";
import {ModulesLibrary} from "@aleph-vault/libraries/ModulesLibrary.sol";
import {PausableFlows} from "@aleph-vault/libraries/PausableFlows.sol";
import {RolesLibrary} from "@aleph-vault/libraries/RolesLibrary.sol";
import {SeriesAccounting} from "@aleph-vault/libraries/SeriesAccounting.sol";
import {AlephPausable} from "@aleph-vault/AlephPausable.sol";
import {AlephVaultBase} from "@aleph-vault/AlephVaultBase.sol";
import {AlephVaultStorageData} from "@aleph-vault/AlephVaultStorage.sol";

/**
 * @author Othentic Labs LTD.
 * @notice Terms of Service: https://aleph.finance/terms-of-service
 * @dev Functions that use _delegate() may have parameters that appear unused
 *      but are actually passed through to the delegated implementation via calldata
 */
contract AlephVault is IAlephVault, AlephVaultBase, AlephPausable {
    /*//////////////////////////////////////////////////////////////
                            MODIFIERS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Modifier to check if a share class id is valid
     * @param _classId The share class id
     */
    modifier onlyValidShareClass(uint8 _classId) {
        // check if share class id is valid or not
        if (_classId > _getStorage().shareClassesId || _classId == 0) {
            revert InvalidShareClass();
        }
        _;
    }

    /**
     * @notice Modifier to check if a share class and series id are valid
     * @param _classId The share class id
     * @param _seriesId The share series id
     */
    modifier onlyValidShareClassAndSeries(uint8 _classId, uint32 _seriesId) {
        AlephVaultStorageData storage _sd = _getStorage();
        // check if share class id is valid or not
        if (_classId > _sd.shareClassesId || _classId == 0) {
            revert InvalidShareClass();
        }
        // check if share series id is valid or not
        // series that haven't been created yet or that have been consolidated are considered invalid
        IAlephVault.ShareClass storage _shareClass = _sd.shareClasses[_classId];
        if (
            _seriesId > _shareClass.shareSeriesId
                || (_seriesId > SeriesAccounting.LEAD_SERIES_ID && _seriesId <= _shareClass.lastConsolidatedSeriesId)
        ) {
            revert InvalidShareSeries();
        }
        _;
    }

    /*//////////////////////////////////////////////////////////////
                            CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Constructor.
     * @param _batchDuration The duration of a batch.
     */
    constructor(uint48 _batchDuration) AlephVaultBase(_batchDuration) {}

    /*//////////////////////////////////////////////////////////////
                            INITIALIZER
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Initializes the vault with the given parameters.
     * @param _initializationParams Struct containing all initialization parameters.
     */
    function initialize(InitializationParams calldata _initializationParams) public initializer {
        _initialize(_initializationParams);
    }

    /**
     * @dev Internal function to set up vault storage and roles.
     * @param _initializationParams Struct containing all initialization parameters.
     */
    function _initialize(InitializationParams calldata _initializationParams) internal onlyInitializing {
        AlephVaultStorageData storage _sd = _getStorage();
        __AccessControl_init();
        if (
            _initializationParams.operationsMultisig == address(0) || _initializationParams.vaultFactory == address(0)
                || _initializationParams.oracle == address(0) || _initializationParams.guardian == address(0)
                || _initializationParams.authSigner == address(0)
                || _initializationParams.userInitializationParams.underlyingToken == address(0)
                || _initializationParams.userInitializationParams.custodian == address(0)
                || _initializationParams.accountant == address(0)
                || _initializationParams.moduleInitializationParams.alephVaultDepositImplementation == address(0)
                || _initializationParams.moduleInitializationParams.alephVaultRedeemImplementation == address(0)
                || _initializationParams.moduleInitializationParams.alephVaultSettlementImplementation == address(0)
                || _initializationParams.moduleInitializationParams.feeManagerImplementation == address(0)
                || _initializationParams.moduleInitializationParams.migrationManagerImplementation == address(0)
                || _initializationParams.userInitializationParams.shareClassParams.managementFee > MAXIMUM_MANAGEMENT_FEE
                || _initializationParams.userInitializationParams.shareClassParams.performanceFee > MAXIMUM_PERFORMANCE_FEE
                || _initializationParams.userInitializationParams.shareClassParams.minDepositAmount == 0
                || _initializationParams.userInitializationParams.shareClassParams.minRedeemAmount == 0
        ) {
            revert InvalidInitializationParams();
        }
        // set up storage variables
        _sd.operationsMultisig = _initializationParams.operationsMultisig;
        _sd.manager = _initializationParams.manager;
        _sd.oracle = _initializationParams.oracle;
        _sd.guardian = _initializationParams.guardian;
        _sd.authSigner = _initializationParams.authSigner;
        _sd.accountant = _initializationParams.accountant;
        _sd.name = _initializationParams.userInitializationParams.name;
        _sd.underlyingToken = _initializationParams.userInitializationParams.underlyingToken;
        _sd.custodian = _initializationParams.userInitializationParams.custodian;
        _sd.isDepositAuthEnabled = true;
        _sd.isSettlementAuthEnabled = true;
        _sd.startTimeStamp = Time.timestamp();

        // set up module implementations
        _sd.moduleImplementations[ModulesLibrary.ALEPH_VAULT_DEPOSIT] =
            _initializationParams.moduleInitializationParams.alephVaultDepositImplementation;
        _sd.moduleImplementations[ModulesLibrary.ALEPH_VAULT_REDEEM] =
            _initializationParams.moduleInitializationParams.alephVaultRedeemImplementation;
        _sd.moduleImplementations[ModulesLibrary.ALEPH_VAULT_SETTLEMENT] =
            _initializationParams.moduleInitializationParams.alephVaultSettlementImplementation;
        _sd.moduleImplementations[ModulesLibrary.FEE_MANAGER] =
            _initializationParams.moduleInitializationParams.feeManagerImplementation;
        _sd.moduleImplementations[ModulesLibrary.MIGRATION_MANAGER] =
            _initializationParams.moduleInitializationParams.migrationManagerImplementation;

        // grant roles
        _grantRole(RolesLibrary.OPERATIONS_MULTISIG, _initializationParams.operationsMultisig);
        _grantRole(RolesLibrary.VAULT_FACTORY, _initializationParams.vaultFactory);
        _grantRole(RolesLibrary.MANAGER, _initializationParams.manager);
        _grantRole(RolesLibrary.ORACLE, _initializationParams.oracle);
        _grantRole(RolesLibrary.GUARDIAN, _initializationParams.guardian);
        _grantRole(RolesLibrary.ACCOUNTANT, _initializationParams.accountant);

        // initialize pausable modules
        __AlephVaultDeposit_init(
            _initializationParams.manager, _initializationParams.guardian, _initializationParams.operationsMultisig
        );
        __AlephVaultRedeem_init(
            _initializationParams.manager, _initializationParams.guardian, _initializationParams.operationsMultisig
        );
        // initialize reentrancy guard
        __ReentrancyGuard_init();

        // create default share class
        _createShareClass(_sd, _initializationParams.userInitializationParams.shareClassParams);
    }

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /// @inheritdoc IAlephVault
    function startTimeStamp() external view returns (uint48) {
        return _getStorage().startTimeStamp;
    }

    /// @inheritdoc IAlephVault
    function currentBatch() external view returns (uint48) {
        return _currentBatch(_getStorage());
    }

    /// @inheritdoc IAlephVault
    function shareClasses() external view returns (uint8) {
        return _getStorage().shareClassesId;
    }

    /// @inheritdoc IAlephVault
    function shareSeriesId(uint8 _classId) external view onlyValidShareClass(_classId) returns (uint32) {
        return _getStorage().shareClasses[_classId].shareSeriesId;
    }

    /// @inheritdoc IAlephVault
    function lastConsolidatedSeriesId(uint8 _classId) external view returns (uint32) {
        return _getStorage().shareClasses[_classId].lastConsolidatedSeriesId;
    }

    /// @inheritdoc IAlephVault
    function name() external view returns (string memory) {
        return _getStorage().name;
    }

    /// @inheritdoc IAlephVault
    function manager() external view returns (address) {
        return _getStorage().manager;
    }

    /// @inheritdoc IAlephVault
    function underlyingToken() external view returns (address) {
        return _getStorage().underlyingToken;
    }

    /// @inheritdoc IAlephVault
    function custodian() external view returns (address) {
        return _getStorage().custodian;
    }

    /// @inheritdoc IAlephVault
    function vaultTreasury() external view returns (address) {
        return IAccountant(_getStorage().accountant).vaultTreasury();
    }

    /// @inheritdoc IAlephVault
    function operationsMultisig() external view returns (address) {
        return _getStorage().operationsMultisig;
    }

    /// @inheritdoc IAlephVault
    function oracle() external view returns (address) {
        return _getStorage().oracle;
    }

    /// @inheritdoc IAlephVault
    function guardian() external view returns (address) {
        return _getStorage().guardian;
    }

    /// @inheritdoc IAlephVault
    function authSigner() external view returns (address) {
        return _getStorage().authSigner;
    }

    /// @inheritdoc IAlephVault
    function accountant() external view returns (address) {
        return _getStorage().accountant;
    }

    /// @inheritdoc IAlephVault
    function managementFee(uint8 _classId) external view onlyValidShareClass(_classId) returns (uint32) {
        return _getStorage().shareClasses[_classId].shareClassParams.managementFee;
    }

    /// @inheritdoc IAlephVault
    function performanceFee(uint8 _classId) external view onlyValidShareClass(_classId) returns (uint32) {
        return _getStorage().shareClasses[_classId].shareClassParams.performanceFee;
    }

    /// @inheritdoc IAlephVault
    function noticePeriod(uint8 _classId) external view onlyValidShareClass(_classId) returns (uint48) {
        return _getStorage().shareClasses[_classId].shareClassParams.noticePeriod;
    }

    /// @inheritdoc IAlephVault
    function lockInPeriod(uint8 _classId) external view onlyValidShareClass(_classId) returns (uint48) {
        return _getStorage().shareClasses[_classId].shareClassParams.lockInPeriod;
    }

    /// @inheritdoc IAlephVault
    function minDepositAmount(uint8 _classId) external view onlyValidShareClass(_classId) returns (uint256) {
        return _getStorage().shareClasses[_classId].shareClassParams.minDepositAmount;
    }

    /// @inheritdoc IAlephVault
    function minUserBalance(uint8 _classId) external view onlyValidShareClass(_classId) returns (uint256) {
        return _getStorage().shareClasses[_classId].shareClassParams.minUserBalance;
    }

    /// @inheritdoc IAlephVault
    function maxDepositCap(uint8 _classId) external view onlyValidShareClass(_classId) returns (uint256) {
        return _getStorage().shareClasses[_classId].shareClassParams.maxDepositCap;
    }

    /// @inheritdoc IAlephVault
    function minRedeemAmount(uint8 _classId) external view onlyValidShareClass(_classId) returns (uint256) {
        return _getStorage().shareClasses[_classId].shareClassParams.minRedeemAmount;
    }

    /// @inheritdoc IAlephVault
    function userLockInPeriod(uint8 _classId, address _user)
        external
        view
        onlyValidShareClass(_classId)
        returns (uint48)
    {
        return _getStorage().shareClasses[_classId].userLockInPeriod[_user];
    }

    /// @inheritdoc IAlephVault
    function redeemableAmount(address _user) external view returns (uint256) {
        return _getStorage().redeemableAmount[_user];
    }

    /// @inheritdoc IAlephVault
    function isDepositAuthEnabled() external view returns (bool) {
        return _getStorage().isDepositAuthEnabled;
    }

    /// @inheritdoc IAlephVault
    function isSettlementAuthEnabled() external view returns (bool) {
        return _getStorage().isSettlementAuthEnabled;
    }

    /// @inheritdoc IAlephVault
    function totalAssets() external view returns (uint256) {
        return _totalAssets(_getStorage());
    }

    /// @inheritdoc IAlephVault
    function totalAssetsOfClass(uint8 _classId)
        external
        view
        onlyValidShareClass(_classId)
        returns (uint256[] memory)
    {
        IAlephVault.ShareClass storage _shareClass = _getStorage().shareClasses[_classId];
        uint32 _shareSeriesId = _shareClass.shareSeriesId;
        uint32 _lastConsolidatedSeriesId = _shareClass.lastConsolidatedSeriesId;
        uint32 _len = _shareSeriesId - _lastConsolidatedSeriesId + 1;
        uint256[] memory _totalAssets = new uint256[](_len);
        for (uint32 _i; _i < _len; _i++) {
            uint32 _seriesId =
                _i > SeriesAccounting.LEAD_SERIES_ID ? _lastConsolidatedSeriesId + _i : SeriesAccounting.LEAD_SERIES_ID;
            _totalAssets[_i] = _totalAssetsPerSeries(_shareClass, _classId, _seriesId);
        }
        return _totalAssets;
    }

    /// @inheritdoc IAlephVault
    function totalAssetsPerClass(uint8 _classId) external view onlyValidShareClass(_classId) returns (uint256) {
        return _totalAssetsPerClass(_getStorage().shareClasses[_classId], _classId);
    }

    /// @inheritdoc IAlephVault
    function totalAssetsPerSeries(uint8 _classId, uint32 _seriesId)
        external
        view
        onlyValidShareClassAndSeries(_classId, _seriesId)
        returns (uint256)
    {
        return _totalAssetsPerSeries(_getStorage().shareClasses[_classId], _classId, _seriesId);
    }

    /// @inheritdoc IAlephVault
    function totalSharesPerSeries(uint8 _classId, uint32 _seriesId)
        external
        view
        onlyValidShareClassAndSeries(_classId, _seriesId)
        returns (uint256)
    {
        return _totalSharesPerSeries(_getStorage().shareClasses[_classId], _classId, _seriesId);
    }

    /// @inheritdoc IAlephVault
    function assetsPerClassOf(uint8 _classId, address _user)
        external
        view
        onlyValidShareClass(_classId)
        returns (uint256)
    {
        return _assetsPerClassOf(_getStorage().shareClasses[_classId], _classId, _user);
    }

    /// @inheritdoc IAlephVault
    function assetsOf(uint8 _classId, uint32 _seriesId, address _user)
        external
        view
        onlyValidShareClassAndSeries(_classId, _seriesId)
        returns (uint256)
    {
        return _assetsOf(_getStorage().shareClasses[_classId], _classId, _seriesId, _user);
    }

    /// @inheritdoc IAlephVault
    function sharesOf(uint8 _classId, uint32 _seriesId, address _user)
        external
        view
        onlyValidShareClassAndSeries(_classId, _seriesId)
        returns (uint256)
    {
        return _sharesOf(_getStorage().shareClasses[_classId], _seriesId, _user);
    }

    /// @inheritdoc IAlephVault
    function pricePerShare(uint8 _classId, uint32 _seriesId)
        external
        view
        onlyValidShareClassAndSeries(_classId, _seriesId)
        returns (uint256)
    {
        IAlephVault.ShareClass storage _shareClass = _getStorage().shareClasses[_classId];
        return _getPricePerShare(
            _totalAssetsPerSeries(_shareClass, _classId, _seriesId),
            _totalSharesPerSeries(_shareClass, _classId, _seriesId)
        );
    }

    /// @inheritdoc IAlephVault
    function highWaterMark(uint8 _classId, uint32 _seriesId)
        external
        view
        onlyValidShareClassAndSeries(_classId, _seriesId)
        returns (uint256)
    {
        return _getStorage().shareClasses[_classId].shareSeries[_seriesId].highWaterMark;
    }

    /// @inheritdoc IAlephVault
    function totalAmountToDeposit(uint8 _classId) external view onlyValidShareClass(_classId) returns (uint256) {
        return _totalAmountToDeposit(_getStorage(), _classId);
    }

    /// @inheritdoc IAlephVault
    function totalAmountToDepositAt(uint8 _classId, uint48 _batchId)
        external
        view
        onlyValidShareClass(_classId)
        returns (uint256)
    {
        return _getStorage().shareClasses[_classId].depositRequests[_batchId].totalAmountToDeposit;
    }

    /// @inheritdoc IAlephVault
    function depositRequestOf(uint8 _classId, address _user) external view returns (uint256 _totalAmountToDeposit) {
        return _depositRequestOf(_getStorage(), _classId, _user);
    }

    /// @inheritdoc IAlephVault
    function depositRequestOfAt(uint8 _classId, address _user, uint48 _batchId)
        external
        view
        returns (uint256 _amountToDeposit)
    {
        return _getStorage().shareClasses[_classId].depositRequests[_batchId].depositRequest[_user];
    }

    /// @inheritdoc IAlephVault
    function redeemRequestOf(uint8 _classId, address _user) external view returns (uint256 _totalAmountToRedeem) {
        AlephVaultStorageData storage _sd = _getStorage();
        IAlephVault.ShareClass storage _shareClass = _sd.shareClasses[_classId];
        return _pendingAssetsOf(_shareClass, _currentBatch(_sd), _user, _assetsPerClassOf(_shareClass, _classId, _user));
    }

    /// @inheritdoc IAlephVault
    function redeemRequestOfAt(uint8 _classId, address _user, uint48 _batchId)
        external
        view
        returns (uint256 _amountShareToRedeem)
    {
        return _getStorage().shareClasses[_classId].redeemRequests[_batchId].redeemRequest[_user];
    }

    /// @inheritdoc IAlephVault
    function usersToDepositAt(uint8 _classId, uint48 _batchId) external view returns (address[] memory) {
        bytes32[] memory _bytesUsers =
            _getStorage().shareClasses[_classId].depositRequests[_batchId].usersToDeposit._inner._values;
        address[] memory _users = new address[](_bytesUsers.length);
        assembly {
            _users := _bytesUsers
        }
        return _users;
    }

    /// @inheritdoc IAlephVault
    function usersToRedeemAt(uint8 _classId, uint48 _batchId) external view returns (address[] memory) {
        bytes32[] memory _bytesUsers =
            _getStorage().shareClasses[_classId].redeemRequests[_batchId].usersToRedeem._inner._values;
        address[] memory _users = new address[](_bytesUsers.length);
        assembly {
            _users := _bytesUsers
        }
        return _users;
    }

    /// @inheritdoc IAlephVault
    function totalFeeAmountToCollect() external view returns (uint256 _totalFeeAmountToCollect) {
        AlephVaultStorageData storage _sd = _getStorage();
        uint8 _shareClasses = _sd.shareClassesId;
        for (uint8 _classId = 1; _classId <= _shareClasses; _classId++) {
            IAlephVault.ShareClass storage _shareClass = _sd.shareClasses[_classId];
            _totalFeeAmountToCollect +=
                _assetsPerClassOf(_shareClass, _classId, SeriesAccounting.MANAGEMENT_FEE_RECIPIENT);
            _totalFeeAmountToCollect +=
                _assetsPerClassOf(_shareClass, _classId, SeriesAccounting.PERFORMANCE_FEE_RECIPIENT);
        }
    }

    /*//////////////////////////////////////////////////////////////
                            SETTER FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /// @inheritdoc IAlephVault
    function setIsDepositAuthEnabled(bool _isDepositAuthEnabled)
        external
        override(IAlephVault)
        onlyRole(RolesLibrary.MANAGER)
    {
        _getStorage().isDepositAuthEnabled = _isDepositAuthEnabled;
        emit IsDepositAuthEnabledSet(_isDepositAuthEnabled);
    }

    /// @inheritdoc IAlephVault
    function setIsSettlementAuthEnabled(bool _isSettlementAuthEnabled)
        external
        override(IAlephVault)
        onlyRole(RolesLibrary.MANAGER)
    {
        _getStorage().isSettlementAuthEnabled = _isSettlementAuthEnabled;
        emit IsSettlementAuthEnabledSet(_isSettlementAuthEnabled);
    }

    /// @inheritdoc IAlephVault
    function setVaultTreasury(address _vaultTreasury) external override(IAlephVault) onlyRole(RolesLibrary.MANAGER) {
        IAccountant(_getStorage().accountant).setVaultTreasury(_vaultTreasury);
        emit VaultTreasurySet(_vaultTreasury);
    }

    /// @inheritdoc IAlephVault
    function createShareClass(ShareClassParams memory _shareClassParams)
        external
        onlyRole(RolesLibrary.MANAGER)
        returns (uint8 _classId)
    {
        if (
            _shareClassParams.managementFee > MAXIMUM_MANAGEMENT_FEE
                || _shareClassParams.performanceFee > MAXIMUM_PERFORMANCE_FEE || _shareClassParams.minDepositAmount == 0
                || _shareClassParams.minRedeemAmount == 0
        ) {
            revert InvalidShareClassParams();
        }
        return _createShareClass(_getStorage(), _shareClassParams);
    }

    /*//////////////////////////////////////////////////////////////
                            TIMELOCK FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Queues a new minimum deposit amount to be set after the timelock period
     * @param _classId The ID of the share class to set the minimum deposit amount for.
     * @param _minDepositAmount The new minimum deposit amount to queue.
     * @dev Only callable by the MANAGER role.
     */
    function queueMinDepositAmount(uint8 _classId, uint256 _minDepositAmount)
        external
        onlyValidShareClass(_classId)
        onlyRole(RolesLibrary.MANAGER)
    {
        _delegate(ModulesLibrary.ALEPH_VAULT_DEPOSIT);
    }

    /**
     * @notice Queues a new minimum user balance to be set after the timelock period.
     * @param _classId The ID of the share class to set the minimum user balance for.
     * @param _minUserBalance The new minimum user balance to queue.
     * @dev Only callable by the MANAGER role.
     */
    function queueMinUserBalance(uint8 _classId, uint256 _minUserBalance)
        external
        onlyValidShareClass(_classId)
        onlyRole(RolesLibrary.MANAGER)
    {
        _delegate(ModulesLibrary.ALEPH_VAULT_DEPOSIT);
    }

    /**
     * @notice Queues a new maximum deposit cap to be set after the timelock period.
     * @param _classId The ID of the share class to set the maximum deposit cap for.
     * @param _maxDepositCap The new maximum deposit cap to queue.
     * @dev Only callable by the MANAGER role.
     */
    function queueMaxDepositCap(uint8 _classId, uint256 _maxDepositCap)
        external
        onlyValidShareClass(_classId)
        onlyRole(RolesLibrary.MANAGER)
    {
        _delegate(ModulesLibrary.ALEPH_VAULT_DEPOSIT);
    }

    /**
     * @notice Queues a new notice period to be set after the timelock period.
     * @param _classId The ID of the share class to set the notice period for.
     * @param _noticePeriod The new notice period to queue.
     * @dev Only callable by the MANAGER role.
     */
    function queueNoticePeriod(uint8 _classId, uint48 _noticePeriod)
        external
        onlyValidShareClass(_classId)
        onlyRole(RolesLibrary.MANAGER)
    {
        _delegate(ModulesLibrary.ALEPH_VAULT_REDEEM);
    }

    /**
     * @notice Queues a new lock in period to be set after the timelock period.
     * @param _classId The ID of the share class to set the lock in period for.
     * @param _lockInPeriod The new lock in period to queue.
     * @dev Only callable by the MANAGER role.
     */
    function queueLockInPeriod(uint8 _classId, uint48 _lockInPeriod)
        external
        onlyValidShareClass(_classId)
        onlyRole(RolesLibrary.MANAGER)
    {
        _delegate(ModulesLibrary.ALEPH_VAULT_REDEEM);
    }

    /**
     * @notice Queues a new minimum redeem amount to be set after the timelock period.
     * @param _classId The ID of the share class to set the minimum redeem amount for.
     * @param _minRedeemAmount The new minimum redeem amount to queue.
     * @dev Only callable by the MANAGER role.
     */
    function queueMinRedeemAmount(uint8 _classId, uint256 _minRedeemAmount)
        external
        onlyValidShareClass(_classId)
        onlyRole(RolesLibrary.MANAGER)
    {
        _delegate(ModulesLibrary.ALEPH_VAULT_REDEEM);
    }

    /**
     * @notice Queues a new management fee to be set after the timelock period.
     * @param _classId The ID of the share class to set the management fee for.
     * @param _managementFee The new management fee to queue.
     * @dev Only callable by the MANAGER role.
     */
    function queueManagementFee(uint8 _classId, uint32 _managementFee)
        external
        onlyValidShareClass(_classId)
        onlyRole(RolesLibrary.MANAGER)
    {
        _delegate(ModulesLibrary.FEE_MANAGER);
    }

    /**
     * @notice Queues a new performance fee to be set after the timelock period.
     * @param _classId The ID of the share class to set the performance fee for.
     * @param _performanceFee The new performance fee to queue.
     * @dev Only callable by the MANAGER role.
     */
    function queuePerformanceFee(uint8 _classId, uint32 _performanceFee)
        external
        onlyValidShareClass(_classId)
        onlyRole(RolesLibrary.MANAGER)
    {
        _delegate(ModulesLibrary.FEE_MANAGER);
    }

    /**
     * @notice Sets the minimum deposit amount to the queued value after the timelock period.
     * @param _classId The ID of the share class to set the minimum deposit amount for.
     * @dev Only callable by the MANAGER role.
     */
    function setMinDepositAmount(uint8 _classId)
        external
        onlyValidShareClass(_classId)
        onlyRole(RolesLibrary.MANAGER)
    {
        _delegate(ModulesLibrary.ALEPH_VAULT_DEPOSIT);
    }

    /**
     * @notice Sets the minimum user balance to the queued value after the timelock period.
     * @param _classId The ID of the share class to set the minimum user balance for.
     * @dev Only callable by the MANAGER role.
     */
    function setMinUserBalance(uint8 _classId) external onlyValidShareClass(_classId) onlyRole(RolesLibrary.MANAGER) {
        _delegate(ModulesLibrary.ALEPH_VAULT_DEPOSIT);
    }

    /**
     * @notice Sets the maximum deposit cap to the queued value after the timelock period.
     * @param _classId The ID of the share class to set the maximum deposit cap for.
     * @dev Only callable by the MANAGER role.
     */
    function setMaxDepositCap(uint8 _classId) external onlyValidShareClass(_classId) onlyRole(RolesLibrary.MANAGER) {
        _delegate(ModulesLibrary.ALEPH_VAULT_DEPOSIT);
    }

    /**
     * @notice Sets the notice period to the queued value after the timelock period.
     * @param _classId The ID of the share class to set the notice period for.
     * @dev Only callable by the MANAGER role.
     */
    function setNoticePeriod(uint8 _classId) external onlyValidShareClass(_classId) onlyRole(RolesLibrary.MANAGER) {
        _delegate(ModulesLibrary.ALEPH_VAULT_REDEEM);
    }

    /**
     * @notice Sets the lock in period to the queued value after the timelock period.
     * @param _classId The ID of the share class to set the lock in period for.
     * @dev Only callable by the MANAGER role.
     */
    function setLockInPeriod(uint8 _classId) external onlyValidShareClass(_classId) onlyRole(RolesLibrary.MANAGER) {
        _delegate(ModulesLibrary.ALEPH_VAULT_REDEEM);
    }

    /**
     * @notice Sets the minimum redeem amount to the queued value after the timelock period.
     * @param _classId The ID of the share class to set the minimum redeem amount for.
     * @dev Only callable by the MANAGER role.
     */
    function setMinRedeemAmount(uint8 _classId) external onlyValidShareClass(_classId) onlyRole(RolesLibrary.MANAGER) {
        _delegate(ModulesLibrary.ALEPH_VAULT_REDEEM);
    }

    /**
     * @notice Sets the management fee to the queued value after the timelock period.
     * @param _classId The ID of the share class to set the management fee for.
     * @dev Only callable by the MANAGER role.
     */
    function setManagementFee(uint8 _classId) external onlyValidShareClass(_classId) onlyRole(RolesLibrary.MANAGER) {
        _delegate(ModulesLibrary.FEE_MANAGER);
    }

    /**
     * @notice Sets the performance fee to the queued value after the timelock period.
     * @param _classId The ID of the share class to set the performance fee for.
     * @dev Only callable by the MANAGER role.
     */
    function setPerformanceFee(uint8 _classId) external onlyValidShareClass(_classId) onlyRole(RolesLibrary.MANAGER) {
        _delegate(ModulesLibrary.FEE_MANAGER);
    }

    /*//////////////////////////////////////////////////////////////
                            FEE FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Collects all pending fees.
     * @return _managementFeesToCollect The total management fees collected.
     * @return _performanceFeesToCollect The total performance fees collected.
     * @dev Only callable by the ACCOUNTANT role.
     */
    function collectFees()
        external
        onlyRole(RolesLibrary.ACCOUNTANT)
        returns (uint256 _managementFeesToCollect, uint256 _performanceFeesToCollect)
    {
        _delegate(ModulesLibrary.FEE_MANAGER);
    }

    /*//////////////////////////////////////////////////////////////
                            DEPOSIT FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Requests a deposit of assets.
     * @param _requestDepositParams The parameters for the deposit request.
     * @return _batchId The batch ID of the deposit.
     * @dev Only callable when the deposit request flow is not paused.
     */
    function requestDeposit(IAlephVaultDeposit.RequestDepositParams calldata _requestDepositParams)
        external
        onlyValidShareClass(_requestDepositParams.classId)
        whenFlowNotPaused(PausableFlows.DEPOSIT_REQUEST_FLOW)
        returns (uint48 _batchId)
    {
        _delegate(ModulesLibrary.ALEPH_VAULT_DEPOSIT);
    }

    /*//////////////////////////////////////////////////////////////
                            REDEEM FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Requests a redeem of shares.
     * @param _redeemRequestParams The parameters for the redeem request.
     * @return _batchId The batch ID of the redeem.
     * @dev Only callable when the redeem request flow is not paused.
     */
    function requestRedeem(IAlephVaultRedeem.RedeemRequestParams calldata _redeemRequestParams)
        external
        onlyValidShareClass(_redeemRequestParams.classId)
        whenFlowNotPaused(PausableFlows.REDEEM_REQUEST_FLOW)
        returns (uint48 _batchId)
    {
        _delegate(ModulesLibrary.ALEPH_VAULT_REDEEM);
    }

    /**
     * @notice Withdraws the redeemable amount for the user.
     * @dev Only callable when the withdraw flow is not paused.
     */
    function withdrawRedeemableAmount() external whenFlowNotPaused(PausableFlows.WITHDRAW_FLOW) {
        _delegate(ModulesLibrary.ALEPH_VAULT_REDEEM);
    }

    /**
     * @notice Withdraws excess assets from the vault and sends back to custodian.
     * @dev Only callable by the MANAGER role.
     */
    function withdrawExcessAssets() external onlyRole(RolesLibrary.MANAGER) {
        _delegate(ModulesLibrary.ALEPH_VAULT_REDEEM);
    }

    /*//////////////////////////////////////////////////////////////
                            SETTLEMENT FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Settles all pending deposits up to the current batch.
     * @param _settlementParams The parameters for the settlement.
     * @dev Only callable by the ORACLE role.
     */
    function settleDeposit(IAlephVaultSettlement.SettlementParams calldata _settlementParams)
        external
        onlyRole(RolesLibrary.ORACLE)
        onlyValidShareClass(_settlementParams.classId)
        whenFlowNotPaused(PausableFlows.SETTLE_DEPOSIT_FLOW)
    {
        _delegate(ModulesLibrary.ALEPH_VAULT_SETTLEMENT);
    }

    /**
     * @notice Settles all pending redeems up to the current batch.
     * @param _settlementParams The parameters for the settlement.
     * @dev Only callable by the ORACLE role.
     */
    function settleRedeem(IAlephVaultSettlement.SettlementParams calldata _settlementParams)
        external
        onlyRole(RolesLibrary.ORACLE)
        onlyValidShareClass(_settlementParams.classId)
        whenFlowNotPaused(PausableFlows.SETTLE_REDEEM_FLOW)
    {
        _delegate(ModulesLibrary.ALEPH_VAULT_SETTLEMENT);
    }

    /**
     * @notice Forces a redeem for a user.
     * @param _user The user to force redeem for.
     * @dev Only callable by the MANAGER role.
     */
    function forceRedeem(address _user) external onlyRole(RolesLibrary.MANAGER) {
        _delegate(ModulesLibrary.ALEPH_VAULT_SETTLEMENT);
    }

    /*//////////////////////////////////////////////////////////////
                            MIGRATION FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Migrates the operations multisig.
     * @param _newOperationsMultisig The new operations multisig address.
     * @dev Only callable by the VAULT_FACTORY role.
     */
    function migrateOperationsMultisig(address _newOperationsMultisig) external onlyRole(RolesLibrary.VAULT_FACTORY) {
        _delegate(ModulesLibrary.MIGRATION_MANAGER);
    }

    /**
     * @notice Migrates the oracle.
     * @param _newOracle The new oracle address.
     * @dev Only callable by the VAULT_FACTORY role.
     */
    function migrateOracle(address _newOracle) external onlyRole(RolesLibrary.VAULT_FACTORY) {
        _delegate(ModulesLibrary.MIGRATION_MANAGER);
    }

    /**
     * @notice Migrates the guardian.
     * @param _newGuardian The new guardian address.
     * @dev Only callable by the VAULT_FACTORY role.
     */
    function migrateGuardian(address _newGuardian) external onlyRole(RolesLibrary.VAULT_FACTORY) {
        _delegate(ModulesLibrary.MIGRATION_MANAGER);
    }

    /**
     * @notice Migrates the authentication signer.
     * @param _newAuthSigner The new authentication signer address.
     * @dev Only callable by the VAULT_FACTORY role.
     */
    function migrateAuthSigner(address _newAuthSigner) external onlyRole(RolesLibrary.VAULT_FACTORY) {
        _delegate(ModulesLibrary.MIGRATION_MANAGER);
    }

    /**
     * @notice Migrates the module implementation.
     * @param _module The module selector to migrate.
     * @param _newImplementation The new implementation address for the module.
     * @dev Only callable by the VAULT_FACTORY role.
     */
    function migrateModules(bytes4 _module, address _newImplementation) external onlyRole(RolesLibrary.VAULT_FACTORY) {
        _delegate(ModulesLibrary.MIGRATION_MANAGER);
    }

    /*//////////////////////////////////////////////////////////////
                            INTERNAL FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @dev Internal function to create a new share class.
     * @param _sd The storage struct.
     * @param _shareClassParams The parameters for the share class.
     * @return _classId The ID of the new share class.
     */
    function _createShareClass(AlephVaultStorageData storage _sd, ShareClassParams memory _shareClassParams)
        internal
        returns (uint8 _classId)
    {
        // increment share classes id
        _classId = ++_sd.shareClassesId;
        // set up share class parameters
        IAlephVault.ShareClass storage _shareClass = _sd.shareClasses[_classId];
        _shareClass.shareClassParams = _shareClassParams;
        // set up lead series for new share class
        _shareClass.shareSeries[SeriesAccounting.LEAD_SERIES_ID].highWaterMark = SeriesAccounting.PRICE_DENOMINATOR;
        emit ShareClassCreated(_classId, _shareClassParams);
        return _classId;
    }

    /**
     * @dev Delegates a call to the implementation of the given module.
     * @param _module The module to delegate to.
     */
    function _delegate(bytes4 _module) internal {
        address _implementation = _getStorage().moduleImplementations[_module];
        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), _implementation, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }
}
"
    },
    "lib/openzeppelin-contracts/contracts/utils/types/Time.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/types/Time.sol)

pragma solidity ^0.8.20;

import {Math} from "../math/Math.sol";
import {SafeCast} from "../math/SafeCast.sol";

/**
 * @dev This library provides helpers for manipulating time-related objects.
 *
 * It uses the following types:
 * - `uint48` for timepoints
 * - `uint32` for durations
 *
 * While the library doesn't provide specific types for timepoints and duration, it does provide:
 * - a `Delay` type to represent duration that can be programmed to change value automatically at a given point
 * - additional helper functions
 */
library Time {
    using Time for *;

    /**
     * @dev Get the block timestamp as a Timepoint.
     */
    function timestamp() internal view returns (uint48) {
        return SafeCast.toUint48(block.timestamp);
    }

    /**
     * @dev Get the block number as a Timepoint.
     */
    function blockNumber() internal view returns (uint48) {
        return SafeCast.toUint48(block.number);
    }

    // ==================================================== Delay =====================================================
    /**
     * @dev A `Delay` is a uint32 duration that can be programmed to change value automatically at a given point in the
     * future. The "effect" timepoint describes when the transitions happens from the "old" value to the "new" value.
     * This allows updating the delay applied to some operation while keeping some guarantees.
     *
     * In particular, the {update} function guarantees that if the delay is reduced, the old delay still applies for
     * some time. For example if the delay is currently 7 days to do an upgrade, the admin should not be able to set
     * the delay to 0 and upgrade immediately. If the admin wants to reduce the delay, the old delay (7 days) should
     * still apply for some time.
     *
     *
     * The `Delay` type is 112 bits long, and packs the following:
     *
     * ```
     *   | [uint48]: effect date (timepoint)
     *   |           | [uint32]: value before (duration)
     *   ↓           ↓       ↓ [uint32]: value after (duration)
     * 0xAAAAAAAAAAAABBBBBBBBCCCCCCCC
     * ```
     *
     * NOTE: The {get} and {withUpdate} functions operate using timestamps. Block number based delays are not currently
     * supported.
     */
    type Delay is uint112;

    /**
     * @dev Wrap a duration into a Delay to add the one-step "update in the future" feature
     */
    function toDelay(uint32 duration) internal pure returns (Delay) {
        return Delay.wrap(duration);
    }

    /**
     * @dev Get the value at a given timepoint plus the pending value and effect timepoint if there is a scheduled
     * change after this timepoint. If the effect timepoint is 0, then the pending value should not be considered.
     */
    function _getFullAt(
        Delay self,
        uint48 timepoint
    ) private pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) {
        (valueBefore, valueAfter, effect) = self.unpack();
        return effect <= timepoint ? (valueAfter, 0, 0) : (valueBefore, valueAfter, effect);
    }

    /**
     * @dev Get the current value plus the pending value and effect timepoint if there is a scheduled change. If the
     * effect timepoint is 0, then the pending value should not be considered.
     */
    function getFull(Delay self) internal view returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) {
        return _getFullAt(self, timestamp());
    }

    /**
     * @dev Get the current value.
     */
    function get(Delay self) internal view returns (uint32) {
        (uint32 delay, , ) = self.getFull();
        return delay;
    }

    /**
     * @dev Update a Delay object so that it takes a new duration after a timepoint that is automatically computed to
     * enforce the old delay at the moment of the update. Returns the updated Delay object and the timestamp when the
     * new delay becomes effective.
     */
    function withUpdate(
        Delay self,
        uint32 newValue,
        uint32 minSetback
    ) internal view returns (Delay updatedDelay, uint48 effect) {
        uint32 value = self.get();
        uint32 setback = uint32(Math.max(minSetback, value > newValue ? value - newValue : 0));
        effect = timestamp() + setback;
        return (pack(value, newValue, effect), effect);
    }

    /**
     * @dev Split a delay into its components: valueBefore, valueAfter and effect (transition timepoint).
     */
    function unpack(Delay self) internal pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) {
        uint112 raw = Delay.unwrap(self);

        valueAfter = uint32(raw);
        valueBefore = uint32(raw >> 32);
        effect = uint48(raw >> 64);

        return (valueBefore, valueAfter, effect);
    }

    /**
     * @dev pack the components into a Delay object.
     */
    function pack(uint32 valueBefore, uint32 valueAfter, uint48 effect) internal pure returns (Delay) {
        return Delay.wrap((uint112(effect) << 64) | (uint112(valueBefore) << 32) | uint112(valueAfter));
    }
}
"
    },
    "src/interfaces/IAccountant.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;
/*
  ______   __                      __       
 /      \ /  |                    /  |      
/$$$$$$  |$$ |  ______    ______  $$ |____  
$$ |__$$ |$$ | /      \  /      \ $$      \ 
$$    $$ |$$ |/$$$$$$  |/$$$$$$  |$$$$$$$  |
$$$$$$$$ |$$ |$$    $$ |$$ |  $$ |$$ |  $$ |
$$ |  $$ |$$ |$$$$$$$$/ $$ |__$$ |$$ |  $$ |
$$ |  $$ |$$ |$$       |$$    $$/ $$ |  $$ |
$$/   $$/ $$/  $$$$$$$/ $$$$$$$/  $$/   $$/ 
                        $$ |                
                        $$ |                
                        $$/                 
*/

/**
 * @author Othentic Labs LTD.
 * @notice Terms of Service: https://aleph.finance/terms-of-service
 */
interface IAccountant {
    /*//////////////////////////////////////////////////////////////
                                EVENTS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Emitted when the operations multisig is set.
     * @param operationsMultisig The new operations multisig.
     */
    event OperationsMultisigSet(address operationsMultisig);

    /**
     * @notice Emitted when the vault factory is set.
     * @param vaultFactory The new vault factory.
     */
    event VaultFactorySet(address vaultFactory);

    /**
     * @notice Emitted when the aleph treasury is set.
     * @param alephTreasury The new aleph treasury.
     */
    event AlephTreasurySet(address alephTreasury);

    /**
     * @notice Emitted when the vault treasury is set.
     * @param vault The vault.
     * @param vaultTreasury The new vault treasury.
     */
    event VaultTreasurySet(address vault, address vaultTreasury);

    /**
     * @notice Emitted when the management fee cut is set.
     * @param vault The vault.
     * @param managementFeeCut The new management fee cut.
     */
    event ManagementFeeCutSet(address vault, uint32 managementFeeCut);

    /**
     * @notice Emitted when the performance fee cut is set.
     * @param vault The vault.
     * @param performanceFeeCut The new performance fee cut.
     */
    event PerformanceFeeCutSet(address vault, uint32 performanceFeeCut);

    /**
     * @notice Emitted when fees are collected.
     * @param vault The vault.
     * @param managementFeesToCollect The management fees to collect.
     * @param performanceFeesToCollect The performance fees to collect.
     * @param vaultFee The vault fee split
     * @param alephFee The aleph fee split
     */
    event FeesCollected(
        address vault,
        uint256 managementFeesToCollect,
        uint256 performanceFeesToCollect,
        uint256 vaultFee,
        uint256 alephFee
    );

    /*//////////////////////////////////////////////////////////////
                                ERRORS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Emitted when the initialization params are invalid.
     */
    error InvalidInitializationParams();

    /**
     * @notice Emitted when the vault is invalid.
     */
    error InvalidVault();

    /**
     * @notice Emitted when the manager is invalid.
     */
    error InvalidManager();

    /**
     * @notice Emitted when the vault treasury is invalid.
     */
    error InvalidVaultTreasury();

    /**
     * @notice Emitted when the vault treasury is not set.
     */
    error VaultTreasuryNotSet();

    /**
     * @notice Emitted when fees are not collected.
     */
    error FeesNotCollected();

    /*//////////////////////////////////////////////////////////////
                                STRUCTS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Initialization params.
     * @param operationsMultisig The operations multisig.
     * @param alephTreasury The aleph treasury.
     */
    struct InitializationParams {
        address operationsMultisig;
        address alephTreasury;
    }

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Returns the vault treasury of the caller.
     * @return The vault treasury.
     */
    function vaultTreasury() external view returns (address);

    /*//////////////////////////////////////////////////////////////
                            SETTER FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Initializes the vault treasury.
     * @param _vault The vault to initialize the treasury for.
     * @param _vaultTreasury The new vault treasury.
     */
    function initializeVaultTreasury(address _vault, address _vaultTreasury) external;

    /**
     * @notice Sets the operations multisig.
     * @param _operationsMultisig The new operations multisig.
     */
    function setOperationsMultisig(address _operationsMultisig) external;

    /**
     * @notice Sets the vault factory.
     * @param _vaultFactory The new vault factory.
     */
    function setVaultFactory(address _vaultFactory) external;

    /**
     * @notice Sets the aleph treasury.
     * @param _alephTreasury The new aleph treasury.
     */
    function setAlephTreasury(address _alephTreasury) external;

    /**
     * @notice Sets the vault treasury.
     * @param _vaultTreasury The new vault treasury.
     */
    function setVaultTreasury(address _vaultTreasury) external;

    /**
     * @notice Sets the management fee cut.
     * @param _vault The vault to set the management fee cut for.
     * @param _managementFeeCut The new management fee cut.
     */
    function setManagementFeeCut(address _vault, uint32 _managementFeeCut) external;

    /**
     * @notice Sets the performance fee cut.
     * @param _vault The vault to set the performance fee cut for.
     * @param _performanceFeeCut The new performance fee cut.
     */
    function setPerformanceFeeCut(address _vault, uint32 _performanceFeeCut) external;

    /*//////////////////////////////////////////////////////////////
                            FEE FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Collects all pending fees from a given vault.
     * @param _vault The vault to collect fees from.
     */
    function collectFees(address _vault) external;
}
"
    },
    "src/interfaces/IAlephVault.sol": {
      "content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;
/*
  ______   __                      __       
 /      \ /  |                    /  |      
/$$$$$$  |$$ |  ______    ______  $$ |____  
$$ |__$$ |$$ | /      \  /      \ $$      \ 
$$    $$ |$$ |/$$$$$$  |/$$$$$$  |$$$$$$$  |
$$$$$$$$ |$$ |$$    $$ |$$ |  $$ |$$ |  $$ |
$$ |  $$ |$$ |$$$$$$$$/ $$ |__$$ |$$ |  $$ |
$$ |  $$ |$$ |$$       |$$    $$/ $$ |  $$ |
$$/   $$/ $$/  $$$$$$$/ $$$$$$$/  $$/   $$/ 
                        $$ |                
                        $$ |                
                        $$/                 
*/

import {EnumerableSet} from "openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol";
import {AuthLibrary} from "@aleph-vault/libraries/AuthLibrary.sol";

/**
 * @author Othentic Labs LTD.
 * @notice Terms of Service: https://aleph.finance/terms-of-service
 */
interface IAlephVault {
    /*//////////////////////////////////////////////////////////////
                                EVENTS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Emitted when the deposit authentication is enabled.
     */
    event IsDepositAuthEnabledSet(bool isDepositAuthEnabled);

    /**
     * @notice Emitted when the settlement authentication is enabled.
     */
    event IsSettlementAuthEnabledSet(bool isSettlementAuthEnabled);

    /**
     * @notice Emitted when the vault treasury is set.
     */
    event VaultTreasurySet(address vaultTreasury);

    /**
     * @notice Emitted when the share class is created.
     */
    event ShareClassCreated(uint8 classId, ShareClassParams shareClassParams);

    /*//////////////////////////////////////////////////////////////
                                ERRORS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Emitted when the initialization params are invalid.
     */
    error InvalidInitializationParams();

    /**
     * @notice Emitted when the auth signer is invalid.
     */
    error InvalidAuthSigner();

    /**
     * @notice Emitted when the share class is invalid.
     */
    error InvalidShareClass();

    /**
     * @notice Emitted when the share series is invalid.
     */
    error InvalidShareSeries();

    /**
     * @notice Emitted when the share class params are invalid.
     */
    error InvalidShareClassParams();

    /*//////////////////////////////////////////////////////////////
                                STRUCTS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Initialization params.
     * @param _operationsMultisig The operations multisig address.
     * @param _vaultFactory The vault factory address.
     * @param _manager The manager address.
     * @param _oracle The oracle address.
     * @param _guardian The guardian address.
     * @param _authSigner The auth signer address.
     * @param _accountant The accountant proxy address.
     * @param _userInitializationParams The user initialization params.
     * @param _moduleInitializationParams The module initialization params.
     */
    struct InitializationParams {
        address operationsMultisig;
        address vaultFactory;
        address manager;
        address oracle;
        address guardian;
        address authSigner;
        address accountant;
        UserInitializationParams userInitializationParams;
        ModuleInitializationParams moduleInitializationParams;
    }

    /**
     * @notice Initialization params provided by the user.
     * @param _name The name of the vault.
     * @param _configId The config ID of the vault.
     * @param _underlyingToken The underlying token address.
     * @param _custodian The custodian address in which vault funds are stored.
     * @param _vaultTreasury The vault treasury address in which fees are collected.
     * @param _shareClassParams The share class params for default share class.
     * @param _authSignature The auth signature to deploy the vault.
     */
    struct UserInitializationParams {
        string name;
        string configId;
        address underlyingToken;
        address custodian;
        address vaultTreasury;
        ShareClassParams shareClassParams;
        AuthLibrary.AuthSignature authSignature;
    }

    /**
     * @notice Initialization params for the modules.
     * @param _alephVaultDepositImplementation The aleph vault deposit implementation address.
     * @param _alephVaultRedeemImplementation The aleph vault redeem implementation address.
     * @param _alephVaultSettlementImplementation The aleph vault settlement implementation address.
     * @param _feeManagerImplementation The fee manager implementation address.
     * @param _migrationManagerImplementation The migration manager implementation address.
     */
    struct ModuleInitializationParams {
        address alephVaultDepositImplementation;
        address alephVaultRedeemImplementation;
        address alephVaultSettlementImplementation;
        address feeManagerImplementation;
        address migrationManagerImplementation;
    }

    /**
     * @notice Parameters for a share class.
     * @param _managementFee The management fee rate in basis points.
     * @param _performanceFee The performance fee rate in basis points.
     * @param _noticePeriod The notice period in batches.
     * @param _lockInPeriod The lock in period in batches.
     * @param _minDepositAmount The minimum deposit amount.
     * @param _minUserBalance The minimum user balance.
     * @param _maxDepositCap The maximum deposit cap.
     * @param _minRedeemAmount The minimum redeem amount.
     * @dev all amounts are denominated in underlying token decimals.
     */
    struct ShareClassParams {
        uint32 managementFee;
        uint32 performanceFee;
        uint48 noticePeriod;
        uint48 lockInPeriod;
        uint256 minDepositAmount;
        uint256 minUserBalance;
        uint256 maxDepositCap;
        uint256 minRedeemAmount;
    }

    /**
     * @notice Structure for a share class.
     * @param _shareSeriesId The number of share series created for the share class.
     * @param _lastConsolidatedSeriesId The ID of the last consolidated share series.
     * @param _lastFeePaidId The last Batch ID in which fees were paid.
     * @param _depositSettleId The last Batch ID in which deposits were settled.
     * @param _redeemSettleId The last Batch ID in which redemptions were settled.
     * @param _shareClassParams The parameters for the share class.
     * @param _shareSeries All share series for the share class.
     * @param _depositRequests The deposit requests made for the share class.
     * @param _redeemRequests The redemption requests made for the share class.
     * @param _userLockInPeriod The lock in period for each user in the share class.
     */
    struct ShareClass {
        uint32 shareSeriesId;
        uint32 lastConsolidatedSeriesId;
        uint48 lastFeePaidId;
        uint48 depositSettleId;
        uint48 redeemSettleId;
        ShareClassParams shareClassParams;
        mapping(uint32 => ShareSeries) shareSeries;
        mapping(uint48 batchId => DepositRequests) depositRequests;
        mapping(uint48 batchId => RedeemRequests) redeemRequests;
        mapping(address user => uint48) userLockInPeriod;
    }

    /**
     * @notice Structure for a share series.
     * @param _totalAssets The total assets in the share series.
     * @param _totalShares The total shares in the share series.
     * @param _highWaterMark The high water mark of the share series.
     * @param _users The users in the share series.
     * @param _sharesOf The shares of each user in the share series.
     * @dev assets and shares are denominated in underlying token decimals.
     * @dev if a share series is consolidated, the values inside this mapping are cleared out.
     */
    struct ShareSeries {
        uint256 totalAssets;
        uint256 totalShares;
        uint256 highWaterMark;
        EnumerableSet.AddressSet users;
        mapping(address => uint256) sharesOf;
    }

    /**
     * @notice Structure for the deposit requests for a share class.
     * @param _totalAmountToDeposit The total amount to deposit for the share class.
     * @param _usersToDeposit The users to deposit for the share class.
     * @param _depositRequest The deposit request for each user in the share class.
     * @dev deposit requests are amounts denominated in underlying token decimals.
     * @dev deposit request values are cleared out after settlement.
     */
    struct DepositRequests {
        uint256 totalAmountToDeposit;
        EnumerableSet.AddressSet usersToDeposit;
        mapping(address => uint256) depositRequest;
    }

    /**
     * @notice Structure for the redemption requests for a share class.
     * @param _usersToRedeem The users to redeem for the share class.
     * @param _redeemRequest The redemption request for each user in the share class.
     * @dev redemption requests are in share units (percentage of remaining total user assets in share class)
     * denominated in TOTAL_SHARE_UNITS (1e18).
     * @dev redemption request values are cleared out after settlement.
     */
    struct RedeemRequests {
        EnumerableSet.AddressSet usersToRedeem;
        mapping(address => uint256) redeemRequest;
    }

    /*//////////////////////////////////////////////////////////////
                            VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////*/
    /**
     * @notice Returns the start time of the vault.
     * @return The start time.
     */
    function startTimeStamp() external view returns (uint48);

    /**
     * @notice Returns the current batch ID based on the elapsed time since start.
     * @return The current batch ID.
     */
    function currentBatch() external view returns (uint48);

    /**
     * @notice Returns the number of share classes in the vault.
     * @return The number of share classes.
     */
    function shareClasses() external view returns (uint8);

    /**
     * @notice Returns the max series ID of the share class.
     * @param _classId The ID of the share class.
     * @return The max series ID of the share class.
     */
    function shareSeriesId(uint8 _classId) external view returns (uint32);

    /**
     * @notice Returns the ID of the last consolidated share series.
     * @param _classId The ID of the share class.
     * @return The ID of the last consolidated share series.
     */
    function lastConsolidatedSeriesId(uint8 _classId) external view returns (uint32);

    /**
     * @notice Returns the name of the vault.
     * @return The name.
     */
    function name() external view returns (string memory);

    /**
     * @notice Returns the manager of the vault.
     * @return The manager.
     */
    function manager() external view returns (address);

    /**
     * @notice Returns the underlying token of the vault.
     * @return The underlying token.
     */
    function underlyingToken() external view returns (address);

    /**
     * @notice Returns the custodian of the vault.
     * @return The custodian.
     */
    function custodian() external view returns (address);

    /**
     * @notice Returns the vault treasury of the vault.
     * @return The vault treasury.
     */
    function vaultTreasury() external view returns (address);

    /**
     * @notice Returns the operations multisig of the vault.
     * @return The operations multisig.
     */
    function operationsMultisig() external view returns (address);

    /**
     * @notice Returns the oracle of the vault.
     * @return The oracle.
     */
    function oracle() external view returns (address);

    /**
     * @notice Returns the guardian of the vault.
     * @return The guardian.
     */
    function guardian() external view returns (address);

    /**
     * @notice Returns the KYC authentication signer of the vault.
     * @return The KYC authentication signer.
     */
    function authSigner() external view returns (address);

    /**
     * @notice Returns the accountant of the vault.
     * @return The accountant.
     */
    function accountant() external view returns (address);

    /**
     * @notice Returns the management fee of the vault.
     * @param _classId The ID of the share class.
     * @return The management fee.
     */
    function managementFee(uint8 _classId) external view returns (uint32);

    /**
     * @notice Returns the performance fee of the vault.
     * @param _classId The ID of the share class.
     * @return The performance fee.
     */
    function performanceFee(uint8 _classId) external view returns (uint32);

    /**
     * @notice Returns the notice period of the vault.
     * @param _classId The ID of the share class.
     * @return The notice period.
     */
    function noticePeriod(uint8 _classId) external view returns (uint48);

    /**
     * @notice Returns the lock in period of the vault.
     * @param _classId The ID of the share class.
     * @return The lock in period.
     */
    function lockInPeriod(uint8 _classId) external view returns (uint48);

    /**
     * @notice Returns the minimum deposit amount.
     * @param _classId The ID of the share class.
     * @return The minimum deposit amount of the share class.
     */
    function minDepositAmount(uint8 _class

Tags:
ERC165, Multisig, Swap, Upgradeable, Multi-Signature, Factory, Oracle|addr:0x9aaf27ca68c34b6f4917ee27066683060b1b64a3|verified:true|block:23578337|tx:0x0e46dc82b6b1803f41dccb92f0c718856b9587ec8383d64223421fb6976eb3ac|first_check:1760513203

Submitted on: 2025-10-15 09:26:44

Comments

Log in to comment.

No comments yet.