{"file_path":"src/oracles/Oracle.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../interfaces/oracles/IOracle.sol\";\n\nimport \"../libraries/SlotLibrary.sol\";\n\ncontract Oracle is IOracle, ContextUpgradeable, ReentrancyGuardUpgradeable {\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    /// @inheritdoc IOracle\n    bytes32 public constant SUBMIT_REPORTS_ROLE = keccak256(\"oracles.Oracle.SUBMIT_REPORTS_ROLE\");\n    /// @inheritdoc IOracle\n    bytes32 public constant ACCEPT_REPORT_ROLE = keccak256(\"oracles.Oracle.ACCEPT_REPORT_ROLE\");\n    /// @inheritdoc IOracle\n    bytes32 public constant SET_SECURITY_PARAMS_ROLE = keccak256(\"oracles.Oracle.SET_SECURITY_PARAMS_ROLE\");\n    /// @inheritdoc IOracle\n    bytes32 public constant ADD_SUPPORTED_ASSETS_ROLE = keccak256(\"oracles.Oracle.ADD_SUPPORTED_ASSETS_ROLE\");\n    /// @inheritdoc IOracle\n    bytes32 public constant REMOVE_SUPPORTED_ASSETS_ROLE = keccak256(\"oracles.Oracle.REMOVE_SUPPORTED_ASSETS_ROLE\");\n\n    bytes32 private immutable _oracleStorageSlot;\n\n    modifier onlyRole(bytes32 role) {\n        if (!IAccessControl(address(_oracleStorage().vault)).hasRole(role, _msgSender())) {\n            revert Forbidden();\n        }\n        _;\n    }\n\n    constructor(string memory name_, uint256 version_) {\n        _oracleStorageSlot = SlotLibrary.getSlot(\"Oracle\", name_, version_);\n        _disableInitializers();\n    }\n\n    // View functions\n\n    /// @inheritdoc IOracle\n    function vault() public view returns (IShareModule) {\n        return _oracleStorage().vault;\n    }\n\n    /// @inheritdoc IOracle\n    function securityParams() public view returns (SecurityParams memory) {\n        return _oracleStorage().securityParams;\n    }\n\n    /// @inheritdoc IOracle\n    function supportedAssets() public view returns (uint256) {\n        return _oracleStorage().supportedAssets.length();\n    }\n\n    /// @inheritdoc IOracle\n    function supportedAssetAt(uint256 index) public view returns (address) {\n        return _oracleStorage().supportedAssets.at(index);\n    }\n\n    /// @inheritdoc IOracle\n    function isSupportedAsset(address asset) public view returns (bool) {\n        return _oracleStorage().supportedAssets.contains(asset);\n    }\n\n    /// @inheritdoc IOracle\n    function getReport(address asset) public view returns (DetailedReport memory) {\n        OracleStorage storage $ = _oracleStorage();\n        if (!$.supportedAssets.contains(asset)) {\n            revert UnsupportedAsset(asset);\n        }\n        return $.reports[asset];\n    }\n\n    /// @inheritdoc IOracle\n    function validatePrice(uint256 priceD18, address asset) public view returns (bool isValid, bool isSuspicious) {\n        OracleStorage storage $ = _oracleStorage();\n        if (!$.supportedAssets.contains(asset)) {\n            return (false, false);\n        }\n        return _validatePrice(priceD18, $.reports[asset], $.securityParams);\n    }\n\n    // Mutable functions\n\n    /// @inheritdoc IFactoryEntity\n    function initialize(bytes calldata initParams) external initializer {\n        __Oracle_init(initParams);\n        emit Initialized(initParams);\n    }\n\n    /// @inheritdoc IOracle\n    function setVault(address vault_) external {\n        if (vault_ == address(0)) {\n            revert ZeroValue();\n        }\n        OracleStorage storage $ = _oracleStorage();\n        if (address($.vault) != address(0)) {\n            revert InvalidInitialization();\n        }\n        $.vault = IShareModule(vault_);\n        emit SetVault(vault_);\n    }\n\n    /// @inheritdoc IOracle\n    function submitReports(Report[] calldata reports) external nonReentrant onlyRole(SUBMIT_REPORTS_ROLE) {\n        OracleStorage storage $ = _oracleStorage();\n        SecurityParams memory securityParams_ = $.securityParams;\n        uint32 depositTimestamp = uint32(block.timestamp - securityParams_.depositInterval);\n        uint32 redeemTimestamp = uint32(block.timestamp - securityParams_.redeemInterval);\n        IShareModule vault_ = $.vault;\n        EnumerableSet.AddressSet storage supportedAssets_ = $.supportedAssets;\n        mapping(address asset => DetailedReport) storage reports_ = $.reports;\n        for (uint256 i = 0; i < reports.length; i++) {\n            Report calldata report = reports[i];\n            if (!supportedAssets_.contains(report.asset)) {\n                revert UnsupportedAsset(report.asset);\n            }\n            if (_handleReport(securityParams_, report.priceD18, reports_[report.asset])) {\n                vault_.handleReport(report.asset, report.priceD18, depositTimestamp, redeemTimestamp);\n            }\n        }\n        emit ReportsSubmitted(reports);\n    }\n\n    /// @inheritdoc IOracle\n    function acceptReport(address asset, uint256 priceD18, uint32 timestamp)\n        external\n        nonReentrant\n        onlyRole(ACCEPT_REPORT_ROLE)\n    {\n        OracleStorage storage $ = _oracleStorage();\n        DetailedReport storage report_ = $.reports[asset];\n        if (!report_.isSuspicious || report_.priceD18 != priceD18 || report_.timestamp != timestamp) {\n            revert InvalidReport();\n        }\n        report_.isSuspicious = false;\n        SecurityParams storage params = $.securityParams;\n        $.vault.handleReport(\n            asset, report_.priceD18, timestamp - params.depositInterval, timestamp - params.redeemInterval\n        );\n        emit ReportAccepted(asset, report_.priceD18, timestamp);\n    }\n\n    /// @inheritdoc IOracle\n    function setSecurityParams(SecurityParams calldata securityParams_) external onlyRole(SET_SECURITY_PARAMS_ROLE) {\n        _setSecurityParams(securityParams_);\n    }\n\n    /// @inheritdoc IOracle\n    function addSupportedAssets(address[] calldata assets) external onlyRole(ADD_SUPPORTED_ASSETS_ROLE) {\n        _addSupportedAssets(assets);\n    }\n\n    /// @inheritdoc IOracle\n    function removeSupportedAssets(address[] calldata assets) external onlyRole(REMOVE_SUPPORTED_ASSETS_ROLE) {\n        OracleStorage storage $ = _oracleStorage();\n        EnumerableSet.AddressSet storage asset_ = $.supportedAssets;\n        mapping(address => DetailedReport) storage reports_ = $.reports;\n        IShareModule vault_ = $.vault;\n        address baseAsset = vault_.feeManager().baseAsset(address(vault_));\n        for (uint256 i = 0; i < assets.length; i++) {\n            if (baseAsset != address(0) && baseAsset == assets[i]) {\n                revert Forbidden();\n            }\n            if (vault_.getQueueCount(assets[i]) > 0) {\n                revert Forbidden();\n            }\n            if (!asset_.remove(assets[i])) {\n                revert UnsupportedAsset(assets[i]);\n            }\n            delete reports_[assets[i]];\n        }\n        emit SupportedAssetsRemoved(assets);\n    }\n\n    // Internal functions\n\n    function __Oracle_init(bytes calldata initParams) internal onlyInitializing {\n        __ReentrancyGuard_init();\n        (SecurityParams memory securityParams_, address[] memory assets_) =\n            abi.decode(initParams, (SecurityParams, address[]));\n        _setSecurityParams(securityParams_);\n        _addSupportedAssets(assets_);\n    }\n\n    function _handleReport(SecurityParams memory params, uint224 priceD18, DetailedReport storage report)\n        internal\n        returns (bool)\n    {\n        if (report.timestamp != 0 && params.timeout + report.timestamp > block.timestamp && !report.isSuspicious) {\n            revert TooEarly(block.timestamp, params.timeout + report.timestamp);\n        }\n        (bool isValid, bool isSuspicious) = _validatePrice(priceD18, report, params);\n        if (!isValid) {\n            revert InvalidPrice(priceD18);\n        }\n        report.priceD18 = priceD18;\n        report.timestamp = uint32(block.timestamp);\n        report.isSuspicious = isSuspicious;\n        return !isSuspicious;\n    }\n\n    function _validatePrice(uint256 priceD18, DetailedReport storage report, SecurityParams memory params)\n        private\n        view\n        returns (bool isValid, bool isSuspicious)\n    {\n        uint256 prevPriceD18 = report.priceD18;\n        if (prevPriceD18 == 0) {\n            return (true, true);\n        }\n        uint256 absoluteDeviation = priceD18 > prevPriceD18 ? priceD18 - prevPriceD18 : prevPriceD18 - priceD18;\n        uint256 relativeDeviationD18 = Math.mulDiv(absoluteDeviation, 1 ether, prevPriceD18);\n        if (absoluteDeviation > params.maxAbsoluteDeviation || relativeDeviationD18 > params.maxRelativeDeviationD18) {\n            return (false, false);\n        }\n        if (report.isSuspicious) {\n            return (true, true);\n        }\n        if (\n            absoluteDeviation > params.suspiciousAbsoluteDeviation\n                || relativeDeviationD18 > params.suspiciousRelativeDeviationD18\n        ) {\n            return (true, true);\n        }\n        return (true, false);\n    }\n\n    function _setSecurityParams(SecurityParams memory params) private {\n        OracleStorage storage $ = _oracleStorage();\n        if (\n            params.maxAbsoluteDeviation == 0 || params.suspiciousAbsoluteDeviation == 0\n                || params.maxRelativeDeviationD18 == 0 || params.suspiciousRelativeDeviationD18 == 0 || params.timeout == 0\n                || params.depositInterval == 0 || params.redeemInterval == 0\n        ) {\n            revert ZeroValue();\n        }\n        $.securityParams = params;\n        emit SecurityParamsSet(params);\n    }\n\n    function _addSupportedAssets(address[] memory assets) private {\n        EnumerableSet.AddressSet storage asset_ = _oracleStorage().supportedAssets;\n        for (uint256 i = 0; i < assets.length; i++) {\n            if (!asset_.add(assets[i])) {\n                revert AlreadySupportedAsset(assets[i]);\n            }\n        }\n        emit SupportedAssetsAdded(assets);\n    }\n\n    function _oracleStorage() internal view returns (OracleStorage storage $) {\n        bytes32 slot = _oracleStorageSlot;\n        assembly {\n            $.slot := slot\n        }\n    }\n}\n","deployed_bytecode":"0x608060405234801561000f575f80fd5b506004361061011c575f3560e01c8063816c8850116100a9578063a3bdae3e1161006e578063a3bdae3e146102d0578063a80ce55c14610316578063c663be591461031e578063d4ad5f3814610331578063fbfa77cf14610358575f80fd5b8063816c8850146102365780638f88cbfb146102605780638fe4d996146102735780639be918e6146102865780639f79f613146102a9575f80fd5b806358f3d554116100ef57806358f3d554146101c15780636094fd57146101d45780636817031b146101e95780636c038d03146101fc57806375a3eea41461020f575f80fd5b8063074cd3531461012057806342c74b191461015a578063439fab911461018557806356679cf41461019a575b5f80fd5b6101477f79abe62d91dbd05fcda41b212f4c8c1f1d8be54ccddf859de3ccd1361b71fcb681565b6040519081526020015b60405180910390f35b61016d610168366004611bb2565b610360565b6040516001600160a01b039091168152602001610151565b610198610193366004611bc9565b61037c565b005b6101477f341f4b58682c3a888bdb3eb9a8a4452a6e847be8a380eb3d742794b4f9ac0ab381565b6101986101cf366004611c34565b6104ae565b6101dc61058c565b6040516101519190611c4a565b6101986101f7366004611cd7565b61064e565b61019861020a366004611d0a565b6106f1565b6101477f73c07eddbe5b5274995c8e6cbe94d644cedc04911df3baf934188d230ca7a2cd81565b610249610244366004611d45565b61095b565b604080519215158352901515602083015201610151565b61019861026e366004611d73565b610a38565b610198610281366004611dcf565b610d6a565b610299610294366004611cd7565b610e68565b6040519015158152602001610151565b6101477f748ab7827e75e9f34387e3ded8598f06eb04cc7bb90fff07bc6dc2a74837702181565b6102e36102de366004611cd7565b610e7e565b6040805182516001600160e01b0316815260208084015163ffffffff169082015291810151151590820152606001610151565b610147610f37565b61019861032c366004611dcf565b610f50565b6101477fb54eea9408efadf36da92cc5ecd8af0f45d6dd90de54634bbc5a2113ddcb505d81565b61016d61132b565b5f6103768261036d611343565b60040190611367565b92915050565b5f610385611379565b805490915060ff600160401b82041615906001600160401b03165f811580156103ab5750825b90505f826001600160401b031660011480156103c65750303b155b9050811580156103d4575080155b156103f25760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561041c57845460ff60401b1916600160401b1785555b61042687876113a1565b7f5e399709a9ff1709f6f6be7268c8e5c3eeaa9da9cd9797e78f07ef287c3717fe8787604051610457929190611e2b565b60405180910390a183156104a557845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b7f79abe62d91dbd05fcda41b212f4c8c1f1d8be54ccddf859de3ccd1361b71fcb66104d7611343565b546001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610530573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105549190611e59565b61057157604051631dd2188d60e31b815260040160405180910390fd5b61058861058336849003840184611f98565b6113db565b5050565b6040805160e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526105cc611343565b6040805160e08101825260018301546001600160e01b03908116825260028401541660208201526003909201546001600160401b0380821692840192909252600160401b8104909116606083015263ffffffff600160801b820481166080840152600160a01b8204811660a0840152600160c01b9091041660c0820152919050565b6001600160a01b03811661067557604051637c946ed760e01b815260040160405180910390fd5b5f61067e611343565b80549091506001600160a01b0316156106aa5760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160a01b0319166001600160a01b03831690811782556040517fd459c7242e23d490831b5676a611c4342d899d28f342d89ae80793e56a930f30905f90a25050565b6106f96115a6565b7f341f4b58682c3a888bdb3eb9a8a4452a6e847be8a380eb3d742794b4f9ac0ab3610722611343565b546001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561077b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061079f9190611e59565b6107bc57604051631dd2188d60e31b815260040160405180910390fd5b5f6107c5611343565b6001600160a01b0386165f908152600682016020526040902060018101549192509060ff161580610800575080546001600160e01b03168514155b8061081c5750805463ffffffff858116600160e01b9092041614155b1561083a57604051632d56b1d560e21b815260040160405180910390fd5b6001818101805460ff19169055825482546003850154928501926001600160a01b039092169163974d942e918a916001600160e01b039091169061088b90600160a01b900463ffffffff168a611fc6565b60028601546108a790600160c01b900463ffffffff168b611fc6565b6040518563ffffffff1660e01b81526004016108c69493929190611fe3565b5f604051808303815f87803b1580156108dd575f80fd5b505af11580156108ef573d5f803e3d5ffd5b5050835460405163ffffffff891693506001600160e01b0390911691506001600160a01b038a16907f3a1824dfb9fd7ed29622fdd2dbee7465c0a7c183a50399f3c22dd93275eb81e8905f90a45050505061095660015f8051602061229683398151915255565b505050565b5f805f610966611343565b905061097560048201856115f0565b610985575f809250925050610a31565b6001600160a01b0384165f908152600682016020908152604091829020825160e08101845260018501546001600160e01b0390811682526002860154169281019290925260038401546001600160401b0380821694840194909452600160401b8104909316606083015263ffffffff600160801b840481166080840152600160a01b8404811660a0840152600160c01b90930490921660c0820152610a2b918791611611565b92509250505b9250929050565b610a406115a6565b7fb54eea9408efadf36da92cc5ecd8af0f45d6dd90de54634bbc5a2113ddcb505d610a69611343565b546001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610ac2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ae69190611e59565b610b0357604051631dd2188d60e31b815260040160405180910390fd5b5f610b0c611343565b6040805160e08101825260018301546001600160e01b039081168252600284015416602082015260038301546001600160401b0380821693830193909352600160401b8104909216606082015263ffffffff600160801b830481166080830152600160a01b8304811660a08301819052600160c01b9093041660c08201529192505f90610b99904261201b565b90505f8260c0015163ffffffff1642610bb2919061201b565b84549091506001600160a01b031660048501600686015f5b89811015610d1257368b8b83818110610be557610be561202e565b604002919091019150610c079050610c006020830183611cd7565b85906115f0565b610c4257610c186020820182611cd7565b60405163ee84f40b60e01b81526001600160a01b0390911660048201526024015b60405180910390fd5b610c8988610c566040840160208501612042565b855f610c656020870187611cd7565b6001600160a01b03166001600160a01b031681526020019081526020015f2061170f565b15610d09576001600160a01b03851663974d942e610caa6020840184611cd7565b610cba6040850160208601612042565b8a8a6040518563ffffffff1660e01b8152600401610cdb9493929190611fe3565b5f604051808303815f87803b158015610cf2575f80fd5b505af1158015610d04573d5f803e3d5ffd5b505050505b50600101610bca565b507f6207881df9938c524ec52b013997b3ef32ee1920c23952e3c43835a4136ba3308a8a604051610d4492919061205b565b60405180910390a1505050505050505061058860015f8051602061229683398151915255565b7f73c07eddbe5b5274995c8e6cbe94d644cedc04911df3baf934188d230ca7a2cd610d93611343565b546001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610dec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e109190611e59565b610e2d57604051631dd2188d60e31b815260040160405180910390fd5b6109568383808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061182c92505050565b5f61037682610e75611343565b600401906115f0565b604080516060810182525f8082526020820181905291810182905290610ea2611343565b9050610eb160048201846115f0565b610ed95760405163ee84f40b60e01b81526001600160a01b0384166004820152602401610c39565b6001600160a01b039092165f90815260069092016020908152604092839020835160608101855281546001600160e01b038116825263ffffffff600160e01b90910416928101929092526001015460ff161515928101929092525090565b5f610f4b610f43611343565b6004016118f0565b905090565b7f748ab7827e75e9f34387e3ded8598f06eb04cc7bb90fff07bc6dc2a748377021610f79611343565b546001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610fd2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ff69190611e59565b61101357604051631dd2188d60e31b815260040160405180910390fd5b5f61101c611343565b80546040805163d0fb020360e01b8152905192935060048085019360068601936001600160a01b0316925f92849263d0fb02039280830192602092918290030181865afa15801561106f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061109391906120c3565b604051630cd9f5f560e11b81526001600160a01b03848116600483015291909116906319b3ebea90602401602060405180830381865afa1580156110d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110fd91906120c3565b90505f5b878110156112e7576001600160a01b03821615801590611158575088888281811061112e5761112e61202e565b90506020020160208101906111439190611cd7565b6001600160a01b0316826001600160a01b0316145b1561117657604051631dd2188d60e31b815260040160405180910390fd5b5f836001600160a01b03166352278ab78b8b858181106111985761119861202e565b90506020020160208101906111ad9190611cd7565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156111ef573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061121391906120de565b111561123257604051631dd2188d60e31b815260040160405180910390fd5b6112638989838181106112475761124761202e565b905060200201602081019061125c9190611cd7565b86906118f9565b61128e578888828181106112795761127961202e565b9050602002016020810190610c189190611cd7565b835f8a8a848181106112a2576112a261202e565b90506020020160208101906112b79190611cd7565b6001600160a01b0316815260208101919091526040015f9081209081556001908101805460ff1916905501611101565b507fc74b9ab6707f00d2a30e1b7c6481ef0ff0b4da5731dbd05125273b1511157bca88886040516113199291906120f5565b60405180910390a15050505050505050565b5f611334611343565b546001600160a01b0316919050565b7fc754dcb8e9addf6b7382997f8388e544437ad27f697fc5beebe71bc3c40f6a0090565b5f611372838361190d565b9392505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610376565b6113a9611933565b6113b161195a565b5f806113bf83850185612142565b915091506113cc826113db565b6113d58161182c565b50505050565b5f6113e4611343565b82519091506001600160e01b03161580611409575060208201516001600160e01b0316155b8061141f575060408201516001600160401b0316155b80611435575060608201516001600160401b0316155b806114485750608082015163ffffffff16155b8061145b575060a082015163ffffffff16155b8061146e575060c082015163ffffffff16155b1561148c57604051637c946ed760e01b815260040160405180910390fd5b81516001820180546001600160e01b039283166001600160e01b03199182161790915560208401516002840180549190931691161790556040808301516003830180546060860151608087015160a088015160c089015163ffffffff908116600160c01b0263ffffffff60c01b19928216600160a01b0263ffffffff60a01b1992909416600160801b029190911667ffffffffffffffff60801b196001600160401b03958616600160401b026fffffffffffffffffffffffffffffffff1990971695909816949094179490941795909516919091171792909216919091179055517fef8badbaaae9b3c2f8c7610a3ff289138f59c38a4f08862894f28d9ab42c112f9061159a908490611c4a565b60405180910390a15050565b5f805160206122968339815191528054600119016115d757604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b60015f8051602061229683398151915255565b6001600160a01b0381165f9081526001830160205260408120541515611372565b81545f9081906001600160e01b0316808203611634576001809250925050611707565b5f81871161164b57611646878361201b565b611655565b611655828861201b565b90505f61166b82670de0b6b3a76400008561196a565b86519091506001600160e01b0316821180611692575085604001516001600160401b031681115b156116a5575f8094509450505050611707565b600187015460ff16156116c15760018094509450505050611707565b85602001516001600160e01b03168211806116e8575085606001516001600160401b031681115b156116fc5760018094509450505050611707565b60015f945094505050505b935093915050565b80545f90600160e01b900463ffffffff1615801590611752575081546080850151429161174a91600160e01b90910463ffffffff1690612204565b63ffffffff16115b80156117635750600182015460ff16155b156117b15781546080850151429161178991600160e01b90910463ffffffff1690612204565b60405163e58369d160e01b8152600481019290925263ffffffff166024820152604401610c39565b5f806117c7856001600160e01b03168588611611565b91509150816117f457604051637cb1974360e11b81526001600160e01b0386166004820152602401610c39565b6001600160e01b038516600160e01b4263ffffffff160217845560018401805460ff1916911580159290921790559150509392505050565b5f611835611343565b60040190505f5b82518110156118c05761187183828151811061185a5761185a61202e565b602002602001015183611a1a90919063ffffffff16565b6118b8578281815181106118875761188761202e565b602002602001015160405163f30f791160e01b8152600401610c3991906001600160a01b0391909116815260200190565b60010161183c565b507f1f029c70079633ea369bfbd5e7d5a4fecb22a0747808ca4b4ad819a655b4a4cf8260405161159a9190612221565b5f610376825490565b5f611372836001600160a01b038416611a2e565b5f825f0182815481106119225761192261202e565b905f5260205f200154905092915050565b61193b611b18565b61195857604051631afcd79f60e31b815260040160405180910390fd5b565b611962611933565b611958611b31565b5f805f6119778686611b39565b91509150815f0361199b578381816119915761199161226d565b0492505050611372565b8184116119b2576119b26003851502601118611b55565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b5f611372836001600160a01b038416611b66565b5f8181526001830160205260408120548015611b08575f611a5060018361201b565b85549091505f90611a639060019061201b565b9050808214611ac2575f865f018281548110611a8157611a8161202e565b905f5260205f200154905080875f018481548110611aa157611aa161202e565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080611ad357611ad3612281565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610376565b5f915050610376565b5092915050565b5f611b21611379565b54600160401b900460ff16919050565b6115dd611933565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b5f818152600183016020526040812054611bab57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610376565b505f610376565b5f60208284031215611bc2575f80fd5b5035919050565b5f8060208385031215611bda575f80fd5b82356001600160401b0380821115611bf0575f80fd5b818501915085601f830112611c03575f80fd5b813581811115611c11575f80fd5b866020828501011115611c22575f80fd5b60209290920196919550909350505050565b5f60e08284031215611c44575f80fd5b50919050565b5f60e08201905060018060e01b038084511683528060208501511660208401525060408301516001600160401b0380821660408501528060608601511660608501525050608083015163ffffffff80821660808501528060a08601511660a08501528060c08601511660c0850152505092915050565b6001600160a01b0381168114611cd4575f80fd5b50565b5f60208284031215611ce7575f80fd5b813561137281611cc0565b803563ffffffff81168114611d05575f80fd5b919050565b5f805f60608486031215611d1c575f80fd5b8335611d2781611cc0565b925060208401359150611d3c60408501611cf2565b90509250925092565b5f8060408385031215611d56575f80fd5b823591506020830135611d6881611cc0565b809150509250929050565b5f8060208385031215611d84575f80fd5b82356001600160401b0380821115611d9a575f80fd5b818501915085601f830112611dad575f80fd5b813581811115611dbb575f80fd5b8660208260061b8501011115611c22575f80fd5b5f8060208385031215611de0575f80fd5b82356001600160401b0380821115611df6575f80fd5b818501915085601f830112611e09575f80fd5b813581811115611e17575f80fd5b8660208260051b8501011115611c22575f80fd5b60208152816020820152818360408301375f818301604090810191909152601f909201601f19160101919050565b5f60208284031215611e69575f80fd5b81518015158114611372575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715611eb457611eb4611e78565b604052919050565b80356001600160e01b0381168114611d05575f80fd5b80356001600160401b0381168114611d05575f80fd5b5f60e08284031215611ef8575f80fd5b60405160e081018181106001600160401b0382111715611f1a57611f1a611e78565b604052905080611f2983611ebc565b8152611f3760208401611ebc565b6020820152611f4860408401611ed2565b6040820152611f5960608401611ed2565b6060820152611f6a60808401611cf2565b6080820152611f7b60a08401611cf2565b60a0820152611f8c60c08401611cf2565b60c08201525092915050565b5f60e08284031215611fa8575f80fd5b6113728383611ee8565b634e487b7160e01b5f52601160045260245ffd5b63ffffffff828116828216039080821115611b1157611b11611fb2565b6001600160a01b039490941684526001600160e01b0392909216602084015263ffffffff908116604084015216606082015260800190565b8181038181111561037657610376611fb2565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215612052575f80fd5b61137282611ebc565b60208082528181018390525f90604080840186845b878110156120b657813561208381611cc0565b6001600160a01b031683526001600160e01b036120a1838701611ebc565b16838601529183019190830190600101612070565b5090979650505050505050565b5f602082840312156120d3575f80fd5b815161137281611cc0565b5f602082840312156120ee575f80fd5b5051919050565b60208082528181018390525f908460408401835b8681101561213757823561211c81611cc0565b6001600160a01b031682529183019190830190600101612109565b509695505050505050565b5f806101008385031215612154575f80fd5b61215e8484611ee8565b915060e08301356001600160401b0380821115612179575f80fd5b818501915085601f83011261218c575f80fd5b81356020828211156121a0576121a0611e78565b8160051b92506121b1818401611e8c565b82815292840181019281810190898511156121ca575f80fd5b948201945b848610156121f457853593506121e484611cc0565b83825294820194908201906121cf565b8096505050505050509250929050565b63ffffffff818116838216019080821115611b1157611b11611fb2565b602080825282518282018190525f9190848201906040850190845b818110156122615783516001600160a01b03168352928401929184019160010161223c565b50909695505050505050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52603160045260245ffdfe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212200dfb0f6e2d5483f244234e51ffa4976081880141fb3ed5c177b9fadbaf164c3b64736f6c63430008190033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":200},"remappings":[":@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",":@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",":erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",":forge-std/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/src/",":halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",":openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",":openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/"]},"optimization_runs":200,"sourcify_repo_url":"https://repo.sourcify.dev/contracts/full_match/1/0x0000000F0d3D1c31b72368366A4049C05E291D58/","decoded_constructor_args":[["Mellow",{"internalType":"string","name":"name_","type":"string"}],["1",{"internalType":"uint256","name":"version_","type":"uint256"}]],"compiler_version":"0.8.25+commit.b61c2a91","is_verified_via_verifier_alliance":false,"verified_at":"2025-09-17T08:15:13.571406Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60a060405234801561000f575f80fd5b506040516125e93803806125e983398101604081905261002e916101b4565b6040805180820190915260068152654f7261636c6560d01b6020820152610056908383610068565b6080526100616100d9565b50506102e6565b5f60ff5f1b1960018585856040516020016100859392919061027f565b604051602081830303815290604052805190602001205f1c6100a791906102c7565b6040516020016100b991815260200190565b604051602081830303815290604052805190602001201690509392505050565b5f6100e2610176565b805490915068010000000000000000900460ff16156101145760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101735780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b634e487b7160e01b5f52604160045260245ffd5b5f80604083850312156101c5575f80fd5b82516001600160401b03808211156101db575f80fd5b818501915085601f8301126101ee575f80fd5b815181811115610200576102006101a0565b604051601f8201601f19908116603f01168101908382118183101715610228576102286101a0565b81604052828152886020848701011115610240575f80fd5b8260208601602083015e5f602084830101528096505050505050602083015190509250929050565b5f81518060208401855e5f93019283525090919050565b7f6d656c6c6f772e666c657869626c652d7661756c74732e73746f726167652e0081525f6102b96102b3601f840187610268565b85610268565b928352505060200192915050565b8181038181111561019a57634e487b7160e01b5f52601160045260245ffd5b6080516122eb6102fe5f395f61134501526122eb5ff3fe608060405234801561000f575f80fd5b506004361061011c575f3560e01c8063816c8850116100a9578063a3bdae3e1161006e578063a3bdae3e146102d0578063a80ce55c14610316578063c663be591461031e578063d4ad5f3814610331578063fbfa77cf14610358575f80fd5b8063816c8850146102365780638f88cbfb146102605780638fe4d996146102735780639be918e6146102865780639f79f613146102a9575f80fd5b806358f3d554116100ef57806358f3d554146101c15780636094fd57146101d45780636817031b146101e95780636c038d03146101fc57806375a3eea41461020f575f80fd5b8063074cd3531461012057806342c74b191461015a578063439fab911461018557806356679cf41461019a575b5f80fd5b6101477f79abe62d91dbd05fcda41b212f4c8c1f1d8be54ccddf859de3ccd1361b71fcb681565b6040519081526020015b60405180910390f35b61016d610168366004611bb2565b610360565b6040516001600160a01b039091168152602001610151565b610198610193366004611bc9565b61037c565b005b6101477f341f4b58682c3a888bdb3eb9a8a4452a6e847be8a380eb3d742794b4f9ac0ab381565b6101986101cf366004611c34565b6104ae565b6101dc61058c565b6040516101519190611c4a565b6101986101f7366004611cd7565b61064e565b61019861020a366004611d0a565b6106f1565b6101477f73c07eddbe5b5274995c8e6cbe94d644cedc04911df3baf934188d230ca7a2cd81565b610249610244366004611d45565b61095b565b604080519215158352901515602083015201610151565b61019861026e366004611d73565b610a38565b610198610281366004611dcf565b610d6a565b610299610294366004611cd7565b610e68565b6040519015158152602001610151565b6101477f748ab7827e75e9f34387e3ded8598f06eb04cc7bb90fff07bc6dc2a74837702181565b6102e36102de366004611cd7565b610e7e565b6040805182516001600160e01b0316815260208084015163ffffffff169082015291810151151590820152606001610151565b610147610f37565b61019861032c366004611dcf565b610f50565b6101477fb54eea9408efadf36da92cc5ecd8af0f45d6dd90de54634bbc5a2113ddcb505d81565b61016d61132b565b5f6103768261036d611343565b60040190611367565b92915050565b5f610385611379565b805490915060ff600160401b82041615906001600160401b03165f811580156103ab5750825b90505f826001600160401b031660011480156103c65750303b155b9050811580156103d4575080155b156103f25760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561041c57845460ff60401b1916600160401b1785555b61042687876113a1565b7f5e399709a9ff1709f6f6be7268c8e5c3eeaa9da9cd9797e78f07ef287c3717fe8787604051610457929190611e2b565b60405180910390a183156104a557845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b7f79abe62d91dbd05fcda41b212f4c8c1f1d8be54ccddf859de3ccd1361b71fcb66104d7611343565b546001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610530573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105549190611e59565b61057157604051631dd2188d60e31b815260040160405180910390fd5b61058861058336849003840184611f98565b6113db565b5050565b6040805160e0810182525f80825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526105cc611343565b6040805160e08101825260018301546001600160e01b03908116825260028401541660208201526003909201546001600160401b0380821692840192909252600160401b8104909116606083015263ffffffff600160801b820481166080840152600160a01b8204811660a0840152600160c01b9091041660c0820152919050565b6001600160a01b03811661067557604051637c946ed760e01b815260040160405180910390fd5b5f61067e611343565b80549091506001600160a01b0316156106aa5760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160a01b0319166001600160a01b03831690811782556040517fd459c7242e23d490831b5676a611c4342d899d28f342d89ae80793e56a930f30905f90a25050565b6106f96115a6565b7f341f4b58682c3a888bdb3eb9a8a4452a6e847be8a380eb3d742794b4f9ac0ab3610722611343565b546001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561077b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061079f9190611e59565b6107bc57604051631dd2188d60e31b815260040160405180910390fd5b5f6107c5611343565b6001600160a01b0386165f908152600682016020526040902060018101549192509060ff161580610800575080546001600160e01b03168514155b8061081c5750805463ffffffff858116600160e01b9092041614155b1561083a57604051632d56b1d560e21b815260040160405180910390fd5b6001818101805460ff19169055825482546003850154928501926001600160a01b039092169163974d942e918a916001600160e01b039091169061088b90600160a01b900463ffffffff168a611fc6565b60028601546108a790600160c01b900463ffffffff168b611fc6565b6040518563ffffffff1660e01b81526004016108c69493929190611fe3565b5f604051808303815f87803b1580156108dd575f80fd5b505af11580156108ef573d5f803e3d5ffd5b5050835460405163ffffffff891693506001600160e01b0390911691506001600160a01b038a16907f3a1824dfb9fd7ed29622fdd2dbee7465c0a7c183a50399f3c22dd93275eb81e8905f90a45050505061095660015f8051602061229683398151915255565b505050565b5f805f610966611343565b905061097560048201856115f0565b610985575f809250925050610a31565b6001600160a01b0384165f908152600682016020908152604091829020825160e08101845260018501546001600160e01b0390811682526002860154169281019290925260038401546001600160401b0380821694840194909452600160401b8104909316606083015263ffffffff600160801b840481166080840152600160a01b8404811660a0840152600160c01b90930490921660c0820152610a2b918791611611565b92509250505b9250929050565b610a406115a6565b7fb54eea9408efadf36da92cc5ecd8af0f45d6dd90de54634bbc5a2113ddcb505d610a69611343565b546001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610ac2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ae69190611e59565b610b0357604051631dd2188d60e31b815260040160405180910390fd5b5f610b0c611343565b6040805160e08101825260018301546001600160e01b039081168252600284015416602082015260038301546001600160401b0380821693830193909352600160401b8104909216606082015263ffffffff600160801b830481166080830152600160a01b8304811660a08301819052600160c01b9093041660c08201529192505f90610b99904261201b565b90505f8260c0015163ffffffff1642610bb2919061201b565b84549091506001600160a01b031660048501600686015f5b89811015610d1257368b8b83818110610be557610be561202e565b604002919091019150610c079050610c006020830183611cd7565b85906115f0565b610c4257610c186020820182611cd7565b60405163ee84f40b60e01b81526001600160a01b0390911660048201526024015b60405180910390fd5b610c8988610c566040840160208501612042565b855f610c656020870187611cd7565b6001600160a01b03166001600160a01b031681526020019081526020015f2061170f565b15610d09576001600160a01b03851663974d942e610caa6020840184611cd7565b610cba6040850160208601612042565b8a8a6040518563ffffffff1660e01b8152600401610cdb9493929190611fe3565b5f604051808303815f87803b158015610cf2575f80fd5b505af1158015610d04573d5f803e3d5ffd5b505050505b50600101610bca565b507f6207881df9938c524ec52b013997b3ef32ee1920c23952e3c43835a4136ba3308a8a604051610d4492919061205b565b60405180910390a1505050505050505061058860015f8051602061229683398151915255565b7f73c07eddbe5b5274995c8e6cbe94d644cedc04911df3baf934188d230ca7a2cd610d93611343565b546001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610dec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e109190611e59565b610e2d57604051631dd2188d60e31b815260040160405180910390fd5b6109568383808060200260200160405190810160405280939291908181526020018383602002808284375f9201919091525061182c92505050565b5f61037682610e75611343565b600401906115f0565b604080516060810182525f8082526020820181905291810182905290610ea2611343565b9050610eb160048201846115f0565b610ed95760405163ee84f40b60e01b81526001600160a01b0384166004820152602401610c39565b6001600160a01b039092165f90815260069092016020908152604092839020835160608101855281546001600160e01b038116825263ffffffff600160e01b90910416928101929092526001015460ff161515928101929092525090565b5f610f4b610f43611343565b6004016118f0565b905090565b7f748ab7827e75e9f34387e3ded8598f06eb04cc7bb90fff07bc6dc2a748377021610f79611343565b546001600160a01b03166391d1485482336040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610fd2573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ff69190611e59565b61101357604051631dd2188d60e31b815260040160405180910390fd5b5f61101c611343565b80546040805163d0fb020360e01b8152905192935060048085019360068601936001600160a01b0316925f92849263d0fb02039280830192602092918290030181865afa15801561106f573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061109391906120c3565b604051630cd9f5f560e11b81526001600160a01b03848116600483015291909116906319b3ebea90602401602060405180830381865afa1580156110d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110fd91906120c3565b90505f5b878110156112e7576001600160a01b03821615801590611158575088888281811061112e5761112e61202e565b90506020020160208101906111439190611cd7565b6001600160a01b0316826001600160a01b0316145b1561117657604051631dd2188d60e31b815260040160405180910390fd5b5f836001600160a01b03166352278ab78b8b858181106111985761119861202e565b90506020020160208101906111ad9190611cd7565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156111ef573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061121391906120de565b111561123257604051631dd2188d60e31b815260040160405180910390fd5b6112638989838181106112475761124761202e565b905060200201602081019061125c9190611cd7565b86906118f9565b61128e578888828181106112795761127961202e565b9050602002016020810190610c189190611cd7565b835f8a8a848181106112a2576112a261202e565b90506020020160208101906112b79190611cd7565b6001600160a01b0316815260208101919091526040015f9081209081556001908101805460ff1916905501611101565b507fc74b9ab6707f00d2a30e1b7c6481ef0ff0b4da5731dbd05125273b1511157bca88886040516113199291906120f5565b60405180910390a15050505050505050565b5f611334611343565b546001600160a01b0316919050565b7f000000000000000000000000000000000000000000000000000000000000000090565b5f611372838361190d565b9392505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610376565b6113a9611933565b6113b161195a565b5f806113bf83850185612142565b915091506113cc826113db565b6113d58161182c565b50505050565b5f6113e4611343565b82519091506001600160e01b03161580611409575060208201516001600160e01b0316155b8061141f575060408201516001600160401b0316155b80611435575060608201516001600160401b0316155b806114485750608082015163ffffffff16155b8061145b575060a082015163ffffffff16155b8061146e575060c082015163ffffffff16155b1561148c57604051637c946ed760e01b815260040160405180910390fd5b81516001820180546001600160e01b039283166001600160e01b03199182161790915560208401516002840180549190931691161790556040808301516003830180546060860151608087015160a088015160c089015163ffffffff908116600160c01b0263ffffffff60c01b19928216600160a01b0263ffffffff60a01b1992909416600160801b029190911667ffffffffffffffff60801b196001600160401b03958616600160401b026fffffffffffffffffffffffffffffffff1990971695909816949094179490941795909516919091171792909216919091179055517fef8badbaaae9b3c2f8c7610a3ff289138f59c38a4f08862894f28d9ab42c112f9061159a908490611c4a565b60405180910390a15050565b5f805160206122968339815191528054600119016115d757604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b60015f8051602061229683398151915255565b6001600160a01b0381165f9081526001830160205260408120541515611372565b81545f9081906001600160e01b0316808203611634576001809250925050611707565b5f81871161164b57611646878361201b565b611655565b611655828861201b565b90505f61166b82670de0b6b3a76400008561196a565b86519091506001600160e01b0316821180611692575085604001516001600160401b031681115b156116a5575f8094509450505050611707565b600187015460ff16156116c15760018094509450505050611707565b85602001516001600160e01b03168211806116e8575085606001516001600160401b031681115b156116fc5760018094509450505050611707565b60015f945094505050505b935093915050565b80545f90600160e01b900463ffffffff1615801590611752575081546080850151429161174a91600160e01b90910463ffffffff1690612204565b63ffffffff16115b80156117635750600182015460ff16155b156117b15781546080850151429161178991600160e01b90910463ffffffff1690612204565b60405163e58369d160e01b8152600481019290925263ffffffff166024820152604401610c39565b5f806117c7856001600160e01b03168588611611565b91509150816117f457604051637cb1974360e11b81526001600160e01b0386166004820152602401610c39565b6001600160e01b038516600160e01b4263ffffffff160217845560018401805460ff1916911580159290921790559150509392505050565b5f611835611343565b60040190505f5b82518110156118c05761187183828151811061185a5761185a61202e565b602002602001015183611a1a90919063ffffffff16565b6118b8578281815181106118875761188761202e565b602002602001015160405163f30f791160e01b8152600401610c3991906001600160a01b0391909116815260200190565b60010161183c565b507f1f029c70079633ea369bfbd5e7d5a4fecb22a0747808ca4b4ad819a655b4a4cf8260405161159a9190612221565b5f610376825490565b5f611372836001600160a01b038416611a2e565b5f825f0182815481106119225761192261202e565b905f5260205f200154905092915050565b61193b611b18565b61195857604051631afcd79f60e31b815260040160405180910390fd5b565b611962611933565b611958611b31565b5f805f6119778686611b39565b91509150815f0361199b578381816119915761199161226d565b0492505050611372565b8184116119b2576119b26003851502601118611b55565b5f848688095f868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010185841190960395909502919093039390930492909217029150509392505050565b5f611372836001600160a01b038416611b66565b5f8181526001830160205260408120548015611b08575f611a5060018361201b565b85549091505f90611a639060019061201b565b9050808214611ac2575f865f018281548110611a8157611a8161202e565b905f5260205f200154905080875f018481548110611aa157611aa161202e565b5f918252602080832090910192909255918252600188019052604090208390555b8554869080611ad357611ad3612281565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610376565b5f915050610376565b5092915050565b5f611b21611379565b54600160401b900460ff16919050565b6115dd611933565b5f805f1983850993909202808410938190039390930393915050565b634e487b715f52806020526024601cfd5b5f818152600183016020526040812054611bab57508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610376565b505f610376565b5f60208284031215611bc2575f80fd5b5035919050565b5f8060208385031215611bda575f80fd5b82356001600160401b0380821115611bf0575f80fd5b818501915085601f830112611c03575f80fd5b813581811115611c11575f80fd5b866020828501011115611c22575f80fd5b60209290920196919550909350505050565b5f60e08284031215611c44575f80fd5b50919050565b5f60e08201905060018060e01b038084511683528060208501511660208401525060408301516001600160401b0380821660408501528060608601511660608501525050608083015163ffffffff80821660808501528060a08601511660a08501528060c08601511660c0850152505092915050565b6001600160a01b0381168114611cd4575f80fd5b50565b5f60208284031215611ce7575f80fd5b813561137281611cc0565b803563ffffffff81168114611d05575f80fd5b919050565b5f805f60608486031215611d1c575f80fd5b8335611d2781611cc0565b925060208401359150611d3c60408501611cf2565b90509250925092565b5f8060408385031215611d56575f80fd5b823591506020830135611d6881611cc0565b809150509250929050565b5f8060208385031215611d84575f80fd5b82356001600160401b0380821115611d9a575f80fd5b818501915085601f830112611dad575f80fd5b813581811115611dbb575f80fd5b8660208260061b8501011115611c22575f80fd5b5f8060208385031215611de0575f80fd5b82356001600160401b0380821115611df6575f80fd5b818501915085601f830112611e09575f80fd5b813581811115611e17575f80fd5b8660208260051b8501011115611c22575f80fd5b60208152816020820152818360408301375f818301604090810191909152601f909201601f19160101919050565b5f60208284031215611e69575f80fd5b81518015158114611372575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715611eb457611eb4611e78565b604052919050565b80356001600160e01b0381168114611d05575f80fd5b80356001600160401b0381168114611d05575f80fd5b5f60e08284031215611ef8575f80fd5b60405160e081018181106001600160401b0382111715611f1a57611f1a611e78565b604052905080611f2983611ebc565b8152611f3760208401611ebc565b6020820152611f4860408401611ed2565b6040820152611f5960608401611ed2565b6060820152611f6a60808401611cf2565b6080820152611f7b60a08401611cf2565b60a0820152611f8c60c08401611cf2565b60c08201525092915050565b5f60e08284031215611fa8575f80fd5b6113728383611ee8565b634e487b7160e01b5f52601160045260245ffd5b63ffffffff828116828216039080821115611b1157611b11611fb2565b6001600160a01b039490941684526001600160e01b0392909216602084015263ffffffff908116604084015216606082015260800190565b8181038181111561037657610376611fb2565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215612052575f80fd5b61137282611ebc565b60208082528181018390525f90604080840186845b878110156120b657813561208381611cc0565b6001600160a01b031683526001600160e01b036120a1838701611ebc565b16838601529183019190830190600101612070565b5090979650505050505050565b5f602082840312156120d3575f80fd5b815161137281611cc0565b5f602082840312156120ee575f80fd5b5051919050565b60208082528181018390525f908460408401835b8681101561213757823561211c81611cc0565b6001600160a01b031682529183019190830190600101612109565b509695505050505050565b5f806101008385031215612154575f80fd5b61215e8484611ee8565b915060e08301356001600160401b0380821115612179575f80fd5b818501915085601f83011261218c575f80fd5b81356020828211156121a0576121a0611e78565b8160051b92506121b1818401611e8c565b82815292840181019281810190898511156121ca575f80fd5b948201945b848610156121f457853593506121e484611cc0565b83825294820194908201906121cf565b8096505050505050509250929050565b63ffffffff818116838216019080821115611b1157611b11611fb2565b602080825282518282018190525f9190848201906040850190845b818110156122615783516001600160a01b03168352928401929184019160010161223c565b50909695505050505050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52603160045260245ffdfe9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a26469706673582212200dfb0f6e2d5483f244234e51ffa4976081880141fb3ed5c177b9fadbaf164c3b64736f6c634300081900330000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000064d656c6c6f770000000000000000000000000000000000000000000000000000","name":"Oracle","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"cancun","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":true,"additional_sources":[{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/utils/ReentrancyGuardUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,\n * consider using {ReentrancyGuardTransient} instead.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuardUpgradeable is Initializable {\n    // Booleans are more expensive than uint256 or any type that takes up a full\n    // word because each write operation emits an extra SLOAD to first read the\n    // slot's contents, replace the bits taken up by the boolean, and then write\n    // back. This is the compiler's defense against contract upgrades and\n    // pointer aliasing, and it cannot be disabled.\n\n    // The values being non-zero value makes deployment a bit more expensive,\n    // but in exchange the refund on every call to nonReentrant will be lower in\n    // amount. Since refunds are capped to a percentage of the total\n    // transaction's gas, it is best to keep them low in cases like this one, to\n    // increase the likelihood of the full refund coming into effect.\n    uint256 private constant NOT_ENTERED = 1;\n    uint256 private constant ENTERED = 2;\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard\n    struct ReentrancyGuardStorage {\n        uint256 _status;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.ReentrancyGuard\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\n\n    function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {\n        assembly {\n            $.slot := ReentrancyGuardStorageLocation\n        }\n    }\n\n    /**\n     * @dev Unauthorized reentrant call.\n     */\n    error ReentrancyGuardReentrantCall();\n\n    function __ReentrancyGuard_init() internal onlyInitializing {\n        __ReentrancyGuard_init_unchained();\n    }\n\n    function __ReentrancyGuard_init_unchained() internal onlyInitializing {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        $._status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Prevents a contract from calling itself, directly or indirectly.\n     * Calling a `nonReentrant` function from another `nonReentrant`\n     * function is not supported. It is possible to prevent this from happening\n     * by making the `nonReentrant` function external, and making it call a\n     * `private` function that does the actual work.\n     */\n    modifier nonReentrant() {\n        _nonReentrantBefore();\n        _;\n        _nonReentrantAfter();\n    }\n\n    function _nonReentrantBefore() private {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        // On the first call to nonReentrant, _status will be NOT_ENTERED\n        if ($._status == ENTERED) {\n            revert ReentrancyGuardReentrantCall();\n        }\n\n        // Any calls to nonReentrant after this point will fail\n        $._status = ENTERED;\n    }\n\n    function _nonReentrantAfter() private {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        // By storing the original value once again, a refund is triggered (see\n        // https://eips.ethereum.org/EIPS/eip-2200)\n        $._status = NOT_ENTERED;\n    }\n\n    /**\n     * @dev Returns true if the reentrancy guard is currently set to \"entered\", which indicates there is a\n     * `nonReentrant` function in the call stack.\n     */\n    function _reentrancyGuardEntered() internal view returns (bool) {\n        ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\n        return $._status == ENTERED;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/transparent/TransparentUpgradeableProxy.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.2.0) (proxy/transparent/TransparentUpgradeableProxy.sol)\n\npragma solidity ^0.8.22;\n\nimport {ERC1967Utils} from \"../ERC1967/ERC1967Utils.sol\";\nimport {ERC1967Proxy} from \"../ERC1967/ERC1967Proxy.sol\";\nimport {IERC1967} from \"../../interfaces/IERC1967.sol\";\nimport {ProxyAdmin} from \"./ProxyAdmin.sol\";\n\n/**\n * @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy}\n * does not implement this interface directly, and its upgradeability mechanism is implemented by an internal dispatch\n * mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not\n * include them in the ABI so this interface must be used to interact with it.\n */\ninterface ITransparentUpgradeableProxy is IERC1967 {\n    /// @dev See {UUPSUpgradeable-upgradeToAndCall}\n    function upgradeToAndCall(address newImplementation, bytes calldata data) external payable;\n}\n\n/**\n * @dev This contract implements a proxy that is upgradeable through an associated {ProxyAdmin} instance.\n *\n * To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector\n * clashing], which can potentially be used in an attack, this contract uses the\n * https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two\n * things that go hand in hand:\n *\n * 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if\n * that call matches the {ITransparentUpgradeableProxy-upgradeToAndCall} function exposed by the proxy itself.\n * 2. If the admin calls the proxy, it can call the `upgradeToAndCall` function but any other call won't be forwarded to\n * the implementation. If the admin tries to call a function on the implementation it will fail with an error indicating\n * the proxy admin cannot fallback to the target implementation.\n *\n * These properties mean that the admin account can only be used for upgrading the proxy, so it's best if it's a\n * dedicated account that is not used for anything else. This will avoid headaches due to sudden errors when trying to\n * call a function from the proxy implementation. For this reason, the proxy deploys an instance of {ProxyAdmin} and\n * allows upgrades only if they come through it. You should think of the `ProxyAdmin` instance as the administrative\n * interface of the proxy, including the ability to change who can trigger upgrades by transferring ownership.\n *\n * NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not\n * inherit from that interface, and instead `upgradeToAndCall` is implicitly implemented using a custom dispatch\n * mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to\n * fully implement transparency without decoding reverts caused by selector clashes between the proxy and the\n * implementation.\n *\n * NOTE: This proxy does not inherit from {Context} deliberately. The {ProxyAdmin} of this contract won't send a\n * meta-transaction in any way, and any other meta-transaction setup should be made in the implementation contract.\n *\n * IMPORTANT: This contract avoids unnecessary storage reads by setting the admin only during construction as an\n * immutable variable, preventing any changes thereafter. However, the admin slot defined in ERC-1967 can still be\n * overwritten by the implementation logic pointed to by this proxy. In such cases, the contract may end up in an\n * undesirable state where the admin slot is different from the actual admin. Relying on the value of the admin slot\n * is generally fine if the implementation is trusted.\n *\n * WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the\n * compiler will not check that there are no selector conflicts, due to the note above. A selector clash between any new\n * function and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This\n * could render the `upgradeToAndCall` function inaccessible, preventing upgradeability and compromising transparency.\n */\ncontract TransparentUpgradeableProxy is ERC1967Proxy {\n    // An immutable address for the admin to avoid unnecessary SLOADs before each call\n    // at the expense of removing the ability to change the admin once it's set.\n    // This is acceptable if the admin is always a ProxyAdmin instance or similar contract\n    // with its own ability to transfer the permissions to another account.\n    address private immutable _admin;\n\n    /**\n     * @dev The proxy caller is the current admin, and can't fallback to the proxy target.\n     */\n    error ProxyDeniedAdminAccess();\n\n    /**\n     * @dev Initializes an upgradeable proxy managed by an instance of a {ProxyAdmin} with an `initialOwner`,\n     * backed by the implementation at `_logic`, and optionally initialized with `_data` as explained in\n     * {ERC1967Proxy-constructor}.\n     */\n    constructor(address _logic, address initialOwner, bytes memory _data) payable ERC1967Proxy(_logic, _data) {\n        _admin = address(new ProxyAdmin(initialOwner));\n        // Set the storage value and emit an event for ERC-1967 compatibility\n        ERC1967Utils.changeAdmin(_proxyAdmin());\n    }\n\n    /**\n     * @dev Returns the admin of this proxy.\n     */\n    function _proxyAdmin() internal view virtual returns (address) {\n        return _admin;\n    }\n\n    /**\n     * @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior.\n     */\n    function _fallback() internal virtual override {\n        if (msg.sender == _proxyAdmin()) {\n            if (msg.sig != ITransparentUpgradeableProxy.upgradeToAndCall.selector) {\n                revert ProxyDeniedAdminAccess();\n            } else {\n                _dispatchUpgradeToAndCall();\n            }\n        } else {\n            super._fallback();\n        }\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy. See {ERC1967Utils-upgradeToAndCall}.\n     *\n     * Requirements:\n     *\n     * - If `data` is empty, `msg.value` must be zero.\n     */\n    function _dispatchUpgradeToAndCall() private {\n        (address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes));\n        ERC1967Utils.upgradeToAndCall(newImplementation, data);\n    }\n}\n"},{"file_path":"src/libraries/FenwickTreeLibrary.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\n/// @title FenwickTreeLibrary\n/// @notice Implements a 0-indexed Fenwick Tree (Binary Indexed Tree) for prefix sum operations.\n/// @dev Enables efficient updates and prefix sum queries over a dynamic array.\n///\n/// # Overview\n/// Fenwick Tree is a compact data structure optimized for cumulative frequency computations:\n/// - `update(i, delta)` increments the element at index `i` by signed `delta`.\n/// - `prefixSum(i)` returns the sum of elements in the range `[0, i]`.\n///\n/// This library provides:\n/// - `O(log n)` time complexity for updates and prefix queries.\n/// - `O(1)` fixed cost for extending the tree by doubling its capacity.\n/// - Support only for arrays whose lengths are powers of two (2^k).\n///\n/// # References\n/// - https://cp-algorithms.com/data_structures/fenwick.html\n/// - https://en.wikipedia.org/wiki/Fenwick_tree\nlibrary FenwickTreeLibrary {\n    /// @notice Thrown when initializing with an invalid length (must be power of 2 and nonzero), or during overflow.\n    error InvalidLength();\n\n    /// @notice Thrown when an index is outside the bounds of the tree.\n    error IndexOutOfBounds();\n\n    /// @notice Internal Fenwick Tree structure using a mapping as a flat array.\n    struct Tree {\n        /// @notice Mapping of index to its cumulative value.\n        mapping(uint256 index => int256) _values;\n        /// @notice Length of the tree (must be a power of 2).\n        uint256 _length;\n    }\n\n    /// @notice Initializes the tree with a given length (must be > 0 and power of 2).\n    /// @param tree The Fenwick tree to initialize.\n    /// @param length_ The length of the tree.\n    function initialize(Tree storage tree, uint256 length_) internal {\n        if (tree._length != 0 || length_ == 0 || (length_ & (length_ - 1)) != 0) {\n            revert InvalidLength();\n        }\n        tree._length = length_;\n    }\n\n    /// @notice Returns the current size of the tree.\n    /// @param tree The Fenwick tree.\n    /// @return The length of the tree.\n    function length(Tree storage tree) internal view returns (uint256) {\n        return tree._length;\n    }\n\n    /// @notice Doubles the length of the Fenwick tree while preserving internal state.\n    /// @param tree The Fenwick tree to be extended.\n    function extend(Tree storage tree) internal {\n        uint256 length_ = tree._length;\n        if (length_ >= (1 << 255)) {\n            revert InvalidLength();\n        }\n        tree._length = length_ << 1;\n        tree._values[(length_ << 1) - 1] = tree._values[length_ - 1];\n    }\n\n    /// @notice Updates the tree at the specified index by a given delta.\n    /// @param tree The Fenwick tree.\n    /// @param index Index to modify.\n    /// @param value Value to add (can be negative).\n    function modify(Tree storage tree, uint256 index, int256 value) internal {\n        uint256 length_ = tree._length;\n        if (index >= length_) {\n            revert IndexOutOfBounds();\n        }\n        if (value == 0) {\n            return;\n        }\n        _modify(tree, index, length_, value);\n    }\n\n    /// @dev Internal function to apply Fenwick update logic.\n    /// @param tree The Fenwick tree.\n    /// @param index Index to start updating from.\n    /// @param length_ Length of the tree.\n    /// @param value Value to add.\n    function _modify(Tree storage tree, uint256 index, uint256 length_, int256 value) private {\n        while (index < length_) {\n            tree._values[index] += value;\n            index |= index + 1;\n        }\n    }\n\n    /// @notice Returns the prefix sum from index 0 to `index` (inclusive).\n    /// @param tree The Fenwick tree.\n    /// @param index Right bound index for sum (inclusive).\n    /// @return prefixSum The sum of values from index 0 to `index`.\n    function get(Tree storage tree, uint256 index) internal view returns (int256) {\n        uint256 length_ = tree._length;\n        if (index >= length_) {\n            index = length_ - 1;\n        }\n        return _get(tree, index);\n    }\n\n    /// @dev Internal function to compute prefix sum up to `index`.\n    /// @param tree The Fenwick tree.\n    /// @param index Right bound index for sum (inclusive).\n    /// @return prefixSum The cumulative sum up to and including `index`.\n    function _get(Tree storage tree, uint256 index) private view returns (int256 prefixSum) {\n        assembly (\"memory-safe\") {\n            mstore(0x20, tree.slot)\n            for {} 1 { index := sub(index, 1) } {\n                mstore(0x00, index)\n                prefixSum := add(prefixSum, sload(keccak256(0x00, 0x40)))\n                index := and(index, add(index, 1))\n                if iszero(index) { break }\n            }\n        }\n    }\n\n    /// @notice Returns the sum over the interval [from, to].\n    /// @param tree The Fenwick tree.\n    /// @param from Left bound index (inclusive).\n    /// @param to Right bound index (inclusive).\n    /// @return The sum over the specified interval.\n    function get(Tree storage tree, uint256 from, uint256 to) internal view returns (int256) {\n        if (from > to) {\n            return 0;\n        }\n        return _get(tree, to) - (from == 0 ? int256(0) : _get(tree, from - 1));\n    }\n}\n"},{"file_path":"src/interfaces/queues/IQueue.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../factories/IFactoryEntity.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/structs/Checkpoints.sol\";\n\n/// @title IQueue\n/// @notice Base interface for deposit and redeem queues.\n/// @dev Provides common structure and logic for queue operations such as pricing and vault association.\ninterface IQueue is IFactoryEntity {\n    /// @notice Reverts when a zero input value is supplied where non-zero is required.\n    error ZeroValue();\n\n    /// @notice Reverts when caller is not authorized to perform an action.\n    error Forbidden();\n\n    /// @notice Reverts when an oracle price report is invalid.\n    error InvalidReport();\n\n    /// @notice Reverts when queue interactions are restricted due to governance or ACL pause.\n    error QueuePaused();\n\n    /// @notice Storage layout for a generic queue contract (deposit or redeem).\n    struct QueueStorage {\n        /// @notice The asset managed by this queue (ERC20 or ETH).\n        address asset;\n        /// @notice The vault that this queue is connected to. Only this vault can trigger `handleReport`.\n        address vault;\n        /// @notice Timeline of user request checkpoints.\n        /// @dev Stores a sorted series of (timestamp, value) pairs, where the meaning of `value` is defined by the specific queue implementation.\n        Checkpoints.Trace224 timestamps;\n    }\n\n    /// @notice Returns the associated vault address.\n    function vault() external view returns (address vault);\n\n    /// @notice Returns the asset handled by this queue (ERC20 or ETH).\n    function asset() external view returns (address asset);\n\n    /// @notice Returns true if this queue is eligible for removal by the vault.\n    /// @return removable True if the queue is safe to remove.\n    function canBeRemoved() external view returns (bool removable);\n\n    /// @notice Handles a new price report from the oracle.\n    /// @dev Only callable by the vault. Validates input timestamp and price.\n    /// @param priceD18 Price reported with 18 decimal precision (shares = price * assets).\n    /// @param timestamp Timestamp when the report becomes effective.\n    function handleReport(uint224 priceD18, uint32 timestamp) external;\n\n    /// @notice Emitted when a price report is successfully processed by the queue.\n    /// @param priceD18 Reported price in 18-decimal fixed-point format (shares = assets * price).\n    /// @param timestamp All unprocessed requests with timestamps <= this value were handled using this report.\n    event ReportHandled(uint224 priceD18, uint32 timestamp);\n}\n"},{"file_path":"src/interfaces/hooks/IHook.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\n/// @title IHook\n/// @notice Interface for a generic hook contract used to process asset-related logic during queue execution upon oracle reports.\n/// @dev This interface is intended for both deposit and redeem queues, where additional logic (e.g. wrapping, redistributions, auto-compounding,\n/// liquidity checks) must be executed atomically during queue finalization. Typically called via `delegatecall`.\ninterface IHook {\n    /// @notice Executes custom logic for the given asset and amount during queue processing.\n    /// @dev This function is called via `delegatecall` by the ShareModule or Vault.\n    /// @param asset The address of the ERC20 asset being processed.\n    /// @param assets The amount of the asset involved in the operation.\n    function callHook(address asset, uint256 assets) external;\n}\n"},{"file_path":"src/interfaces/hooks/IRedeemHook.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"./IHook.sol\";\n\n/// @title IRedeemHook\n/// @notice Interface for redeem-side hooks that implement custom logic during asset redemptions.\ninterface IRedeemHook is IHook {\n    /// @notice Returns the amount of liquid (immediately withdrawable) assets available for a given token.\n    /// @dev Used by queues to determine how much can be processed in the current redemption cycle.\n    /// @param asset The address of the ERC20 asset to check.\n    /// @return assets The amount of the asset that is liquid and available.\n    function getLiquidAssets(address asset) external view returns (uint256 assets);\n}\n"},{"file_path":"src/libraries/SlotLibrary.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\n/// @title SlotLibrary\n/// @notice Library for computing deterministic and collision-resistant storage slots\n/// @dev Used to generate unique storage slots for upgradeable modules using string identifiers\nlibrary SlotLibrary {\n    /// @notice Computes a unique storage slot based on the module's identifiers\n    /// @param contractName Logical contract/module name (e.g., \"ShareModule\")\n    /// @param name Human-readable instance name (e.g., \"Mellow\")\n    /// @param version Version number for the module configuration\n    /// @return A bytes32 value representing the derived storage slot\n    function getSlot(string memory contractName, string memory name, uint256 version) internal pure returns (bytes32) {\n        return keccak256(\n            abi.encode(\n                uint256(keccak256(abi.encodePacked(\"mellow.flexible-vaults.storage.\", contractName, name, version))) - 1\n            )\n        ) & ~bytes32(uint256(0xff));\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Utils.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.2.0) (proxy/ERC1967/ERC1967Utils.sol)\n\npragma solidity ^0.8.22;\n\nimport {IBeacon} from \"../beacon/IBeacon.sol\";\nimport {IERC1967} from \"../../interfaces/IERC1967.sol\";\nimport {Address} from \"../../utils/Address.sol\";\nimport {StorageSlot} from \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This library provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots.\n */\nlibrary ERC1967Utils {\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev The `implementation` of the proxy is invalid.\n     */\n    error ERC1967InvalidImplementation(address implementation);\n\n    /**\n     * @dev The `admin` of the proxy is invalid.\n     */\n    error ERC1967InvalidAdmin(address admin);\n\n    /**\n     * @dev The `beacon` of the proxy is invalid.\n     */\n    error ERC1967InvalidBeacon(address beacon);\n\n    /**\n     * @dev An upgrade function sees `msg.value > 0` that may be lost.\n     */\n    error ERC1967NonPayable();\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the ERC-1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        if (newImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(newImplementation);\n        }\n        StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Performs implementation upgrade with additional setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-Upgraded} event.\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) internal {\n        _setImplementation(newImplementation);\n        emit IERC1967.Upgraded(newImplementation);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(newImplementation, data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using\n     * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the ERC-1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        if (newAdmin == address(0)) {\n            revert ERC1967InvalidAdmin(address(0));\n        }\n        StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {IERC1967-AdminChanged} event.\n     */\n    function changeAdmin(address newAdmin) internal {\n        emit IERC1967.AdminChanged(getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is the keccak-256 hash of \"eip1967.proxy.beacon\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the ERC-1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        if (newBeacon.code.length == 0) {\n            revert ERC1967InvalidBeacon(newBeacon);\n        }\n\n        StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;\n\n        address beaconImplementation = IBeacon(newBeacon).implementation();\n        if (beaconImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(beaconImplementation);\n        }\n    }\n\n    /**\n     * @dev Change the beacon and trigger a setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-BeaconUpgraded} event.\n     *\n     * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since\n     * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for\n     * efficiency.\n     */\n    function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {\n        _setBeacon(newBeacon);\n        emit IERC1967.BeaconUpgraded(newBeacon);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract\n     * if an upgrade doesn't perform an initialization call.\n     */\n    function _checkNonPayable() private {\n        if (msg.value > 0) {\n            revert ERC1967NonPayable();\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/extensions/IAccessControlEnumerable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/extensions/IAccessControlEnumerable.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"../IAccessControl.sol\";\n\n/**\n * @dev External interface of AccessControlEnumerable declared to support ERC-165 detection.\n */\ninterface IAccessControlEnumerable is IAccessControl {\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) external view returns (address);\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) external view returns (uint256);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/access/extensions/AccessControlEnumerableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (access/extensions/AccessControlEnumerable.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControlEnumerable} from \"@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol\";\nimport {AccessControlUpgradeable} from \"../AccessControlUpgradeable.sol\";\nimport {EnumerableSet} from \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\n */\nabstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerable, AccessControlUpgradeable {\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.AccessControlEnumerable\n    struct AccessControlEnumerableStorage {\n        mapping(bytes32 role => EnumerableSet.AddressSet) _roleMembers;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.AccessControlEnumerable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant AccessControlEnumerableStorageLocation = 0xc1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e82371705932000;\n\n    function _getAccessControlEnumerableStorage() private pure returns (AccessControlEnumerableStorage storage $) {\n        assembly {\n            $.slot := AccessControlEnumerableStorageLocation\n        }\n    }\n\n    function __AccessControlEnumerable_init() internal onlyInitializing {\n    }\n\n    function __AccessControlEnumerable_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns one of the accounts that have `role`. `index` must be a\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\n     *\n     * Role bearers are not sorted in any particular way, and their ordering may\n     * change at any point.\n     *\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\n     * you perform all queries on the same block. See the following\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\n     * for more information.\n     */\n    function getRoleMember(bytes32 role, uint256 index) public view virtual returns (address) {\n        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();\n        return $._roleMembers[role].at(index);\n    }\n\n    /**\n     * @dev Returns the number of accounts that have `role`. Can be used\n     * together with {getRoleMember} to enumerate all bearers of a role.\n     */\n    function getRoleMemberCount(bytes32 role) public view virtual returns (uint256) {\n        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();\n        return $._roleMembers[role].length();\n    }\n\n    /**\n     * @dev Return all accounts that have `role`\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function getRoleMembers(bytes32 role) public view virtual returns (address[] memory) {\n        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();\n        return $._roleMembers[role].values();\n    }\n\n    /**\n     * @dev Overload {AccessControl-_grantRole} to track enumerable memberships\n     */\n    function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {\n        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();\n        bool granted = super._grantRole(role, account);\n        if (granted) {\n            $._roleMembers[role].add(account);\n        }\n        return granted;\n    }\n\n    /**\n     * @dev Overload {AccessControl-_revokeRole} to track enumerable memberships\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {\n        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();\n        bool revoked = super._revokeRole(role, account);\n        if (revoked) {\n            $._roleMembers[role].remove(account);\n        }\n        return revoked;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/SlotDerivation.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/SlotDerivation.sol)\n// This file was procedurally generated from scripts/generate/templates/SlotDerivation.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for computing storage (and transient storage) locations from namespaces and deriving slots\n * corresponding to standard patterns. The derivation method for array and mapping matches the storage layout used by\n * the solidity language / compiler.\n *\n * See https://docs.soliditylang.org/en/v0.8.20/internals/layout_in_storage.html#mappings-and-dynamic-arrays[Solidity docs for mappings and dynamic arrays.].\n *\n * Example usage:\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using StorageSlot for bytes32;\n *     using SlotDerivation for bytes32;\n *\n *     // Declare a namespace\n *     string private constant _NAMESPACE = \"<namespace>\"; // eg. OpenZeppelin.Slot\n *\n *     function setValueInNamespace(uint256 key, address newValue) internal {\n *         _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value = newValue;\n *     }\n *\n *     function getValueInNamespace(uint256 key) internal view returns (address) {\n *         return _NAMESPACE.erc7201Slot().deriveMapping(key).getAddressSlot().value;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {StorageSlot}.\n *\n * NOTE: This library provides a way to manipulate storage locations in a non-standard way. Tooling for checking\n * upgrade safety will ignore the slots accessed through this library.\n *\n * _Available since v5.1._\n */\nlibrary SlotDerivation {\n    /**\n     * @dev Derive an ERC-7201 slot from a string (namespace).\n     */\n    function erc7201Slot(string memory namespace) internal pure returns (bytes32 slot) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, sub(keccak256(add(namespace, 0x20), mload(namespace)), 1))\n            slot := and(keccak256(0x00, 0x20), not(0xff))\n        }\n    }\n\n    /**\n     * @dev Add an offset to a slot to get the n-th element of a structure or an array.\n     */\n    function offset(bytes32 slot, uint256 pos) internal pure returns (bytes32 result) {\n        unchecked {\n            return bytes32(uint256(slot) + pos);\n        }\n    }\n\n    /**\n     * @dev Derive the location of the first element in an array from the slot where the length is stored.\n     */\n    function deriveArray(bytes32 slot) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, slot)\n            result := keccak256(0x00, 0x20)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, address key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, and(key, shr(96, not(0))))\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bool key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, iszero(iszero(key)))\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bytes32 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, uint256 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, int256 key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, key)\n            mstore(0x20, slot)\n            result := keccak256(0x00, 0x40)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, string memory key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            let length := mload(key)\n            let begin := add(key, 0x20)\n            let end := add(begin, length)\n            let cache := mload(end)\n            mstore(end, slot)\n            result := keccak256(begin, add(length, 0x20))\n            mstore(end, cache)\n        }\n    }\n\n    /**\n     * @dev Derive the location of a mapping element from the key.\n     */\n    function deriveMapping(bytes32 slot, bytes memory key) internal pure returns (bytes32 result) {\n        assembly (\"memory-safe\") {\n            let length := mload(key)\n            let begin := add(key, 0x20)\n            let end := add(begin, length)\n            let cache := mload(end)\n            mstore(end, slot)\n            result := keccak256(begin, add(length, 0x20))\n            mstore(end, cache)\n        }\n    }\n}\n"},{"file_path":"src/interfaces/modules/IBaseModule.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\";\nimport \"@openzeppelin/contracts/utils/StorageSlot.sol\";\n\n/// @notice Interface for base module functionality shared across all modules\n/// @dev Provides basic utilities such as raw storage access, ERC721 receiver support and `receive()` callback\ninterface IBaseModule is IERC721Receiver {\n    /// @notice Returns a reference to a storage slot as a `StorageSlot.Bytes32Slot` struct\n    /// @param slot The keccak256-derived storage slot identifier\n    /// @return A struct exposing the `.value` field stored at the given slot\n    function getStorageAt(bytes32 slot) external pure returns (StorageSlot.Bytes32Slot memory);\n}\n"},{"file_path":"src/interfaces/permissions/IMellowACL.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol\";\n\n/// @notice Interface for the MellowACL contract, which extends OpenZeppelin's AccessControlEnumerable\n/// @dev Adds tracking of which roles are actively in use (i.e., assigned to at least one address)\ninterface IMellowACL is IAccessControlEnumerable {\n    /// @notice Storage layout used to track actively assigned roles\n    struct MellowACLStorage {\n        EnumerableSet.Bytes32Set supportedRoles; // Set of roles that have at least one assigned member\n    }\n\n    /// @notice Returns the total number of unique roles that are currently assigned\n    function supportedRoles() external view returns (uint256);\n\n    /// @notice Returns the role at the specified index in the set of active roles\n    /// @param index Index within the supported role set\n    /// @return role The bytes32 identifier of the role\n    function supportedRoleAt(uint256 index) external view returns (bytes32);\n\n    /// @notice Checks whether a given role is currently active (i.e., has at least one member)\n    /// @param role The bytes32 identifier of the role to check\n    /// @return isActive True if the role has any members assigned\n    function hasSupportedRole(bytes32 role) external view returns (bool);\n\n    /// @notice Emitted when a new role is granted for the first time\n    event RoleAdded(bytes32 indexed role);\n\n    /// @notice Emitted when a role loses its last member\n    event RoleRemoved(bytes32 indexed role);\n}\n"},{"file_path":"src/interfaces/oracles/IOracle.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/access/IAccessControl.sol\";\n\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n\nimport \"../factories/IFactoryEntity.sol\";\nimport \"../modules/IShareModule.sol\";\n\n/// @title IOracle\n/// @notice Interface for the vault price oracle responsible for submitting, validating, and propagating price reports.\n/// @dev The reported price is structured such that the invariant `shares = assets * price` holds true.\n/// @dev Typically used to coordinate deposit, redemption and limit operations across queues, the vault and subvaults.\ninterface IOracle is IFactoryEntity {\n    /// @notice Thrown when an asset is not supported by the oracle.\n    /// @param asset The address of the unsupported asset.\n    error UnsupportedAsset(address asset);\n\n    /// @notice Thrown when attempting to register an asset that is already supported.\n    /// @param asset The address of the already supported asset.\n    error AlreadySupportedAsset(address asset);\n\n    /// @notice Thrown when a suspicious report fails validation due to unexpected data.\n    /// @dev This includes mismatches in price, timestamp, or incorrect `isSuspicios` flag.\n    error InvalidReport();\n\n    /// @notice Thrown when a function receives a zero value where a non-zero value is required.\n    error ZeroValue();\n\n    /// @notice Thrown when a report is submitted before the required timeout period,\n    ///         and the previous report was not marked as suspicious.\n    /// @param timestamp The submitted report timestamp.\n    /// @param minTimestamp The earliest acceptable timestamp based on timeout configuration.\n    error TooEarly(uint256 timestamp, uint256 minTimestamp);\n\n    /// @notice Thrown when the submitted price violates oracle security rules.\n    /// @param priceD18 The submitted price in 18-decimal fixed-point format.\n    error InvalidPrice(uint256 priceD18);\n\n    /// @notice Thrown when the caller lacks the necessary permission to perform the operation.\n    error Forbidden();\n\n    /// @notice Configuration parameters that govern oracle price validation logic and reporting cadence.\n    struct SecurityParams {\n        /// @notice Maximum absolute difference between the new and previous price, beyond which the report is rejected.\n        uint224 maxAbsoluteDeviation;\n        /// @notice Absolute deviation threshold beyond which the report is flagged as suspicious (but not rejected).\n        uint224 suspiciousAbsoluteDeviation;\n        /// @notice Maximum allowed relative price deviation (as a fixed-point value with 18 decimals), beyond which the report is rejected.\n        ///         Example: 0.05 * 1e18 = 5% max relative deviation.\n        uint64 maxRelativeDeviationD18;\n        /// @notice Relative deviation threshold for flagging suspicious reports (in 18-decimal format),\n        ///         beyond which the report is flagged as suspicious (but not rejected).\n        ///         Example: 0.03 * 1e18 = 3% suspicious threshold.\n        uint64 suspiciousRelativeDeviationD18;\n        /// @notice Minimum time in seconds required between two valid non-suspicious reports.\n        uint32 timeout;\n        /// @notice Minimum age (in seconds) a deposit request must have to be eligible for processing by a report submitted at the current timestamp.\n        uint32 depositInterval;\n        /// @notice Minimum age (in seconds) a redemption request must have to be eligible for processing by a report submitted at the current timestamp.\n        uint32 redeemInterval;\n    }\n\n    /// @notice Struct representing a price report submitted to the oracle.\n    /// @dev Used in vault accounting where `shares = (assets * priceD18) / 1e18`.\n    struct Report {\n        address asset; // Address of the asset the price refers to\n        uint224 priceD18; // Asset price in 18-decimal fixed-point format\n    }\n\n    /// @notice Detailed price report used for validation and tracking\n    struct DetailedReport {\n        uint224 priceD18; // Reported asset price in 18-decimal fixed-point format\n        uint32 timestamp; // Timestamp when the report was submitted\n        bool isSuspicious; // Whether the report is flagged as suspicious according to deviation thresholds\n    }\n\n    /// @notice Storage layout of the oracle\n    struct OracleStorage {\n        IShareModule vault; // The vault module that integrates with oracle reports\n        SecurityParams securityParams; // Oracle security configuration\n        EnumerableSet.AddressSet supportedAssets; // List of supported assets\n        mapping(address asset => DetailedReport) reports; // Latest report per asset\n    }\n\n    /// @notice Role required to submit reports\n    function SUBMIT_REPORTS_ROLE() external view returns (bytes32);\n\n    /// @notice Role required to accept suspicious reports\n    function ACCEPT_REPORT_ROLE() external view returns (bytes32);\n\n    /// @notice Role required to update security parameters\n    function SET_SECURITY_PARAMS_ROLE() external view returns (bytes32);\n\n    /// @notice Role required to add new supported assets\n    function ADD_SUPPORTED_ASSETS_ROLE() external view returns (bytes32);\n\n    /// @notice Role required to remove supported assets\n    function REMOVE_SUPPORTED_ASSETS_ROLE() external view returns (bytes32);\n\n    /// @notice Returns the connected vault module\n    function vault() external view returns (IShareModule);\n\n    /// @notice Returns current security parameters\n    function securityParams() external view returns (SecurityParams memory);\n\n    /// @notice Returns total count of supported assets\n    function supportedAssets() external view returns (uint256);\n\n    /// @notice Returns the supported asset at a specific index\n    /// @param index Index in the supported asset set\n    function supportedAssetAt(uint256 index) external view returns (address);\n\n    /// @notice Checks whether an asset is supported\n    /// @param asset Address of the asset\n    function isSupportedAsset(address asset) external view returns (bool);\n\n    /// @notice Returns the most recent detailed report for an asset\n    /// @param asset Address of the asset\n    function getReport(address asset) external view returns (DetailedReport memory);\n\n    /// @notice Validates the given price for a specific asset based on oracle security parameters.\n    /// @dev Evaluates both absolute and relative deviation limits to determine whether the price is valid or suspicious.\n    /// @param priceD18 Price to validate, in 18-decimal fixed-point format.\n    /// @param asset Address of the asset being evaluated.\n    /// @return isValid True if the price is within maximum allowed deviation.\n    /// @return isSuspicious True if the price exceeds the suspicious deviation threshold.\n    function validatePrice(uint256 priceD18, address asset) external view returns (bool isValid, bool isSuspicious);\n\n    /// @notice Submits price reports for supported assets.\n    /// @dev Processes pending deposit and redemption requests across DepositQueue and RedeemQueue contracts.\n    ///      The core processing logic is determined by the ShareModule and Queue contracts.\n    ///      Only callable by accounts with the `SUBMIT_REPORTS_ROLE`.\n    /// @param reports An array of price reports, each specifying the target asset and its latest price (in 18 decimals).\n    ///\n    /// @dev Note: Submitted prices MUST reflect protocol and performance fee deductions, ensuring accurate share issuance.\n    function submitReports(Report[] calldata reports) external;\n\n    /// @notice Accepts a previously suspicious report\n    /// @dev Callable only by account with `ACCEPT_REPORT_ROLE`\n    /// @param asset Address of the asset\n    /// @param priceD18 Timestamp that must match existing suspicious report\n    /// @param timestamp Timestamp that must match existing suspicious report\n    function acceptReport(address asset, uint256 priceD18, uint32 timestamp) external;\n\n    /// @notice Updates oracle security parameters\n    /// @param securityParams_ New security settings\n    function setSecurityParams(SecurityParams calldata securityParams_) external;\n\n    /// @notice Adds multiple new assets to the supported set\n    /// @param assets Array of asset addresses to add\n    function addSupportedAssets(address[] calldata assets) external;\n\n    /// @notice Removes assets from the supported set\n    /// @param assets Array of asset addresses to remove\n    function removeSupportedAssets(address[] calldata assets) external;\n\n    /// @notice Sets the associated vault\n    /// @param vault_ Address of the vault module\n    function setVault(address vault_) external;\n\n    /// @notice Emitted when price reports are submitted\n    event ReportsSubmitted(Report[] reports);\n\n    /// @notice Emitted when a suspicious report is accepted\n    event ReportAccepted(address indexed asset, uint224 indexed priceD18, uint32 indexed timestamp);\n\n    /// @notice Emitted when new security parameters are set\n    event SecurityParamsSet(SecurityParams securityParams);\n\n    /// @notice Emitted when new assets are added\n    event SupportedAssetsAdded(address[] assets);\n\n    /// @notice Emitted when supported assets are removed\n    event SupportedAssetsRemoved(address[] assets);\n\n    /// @notice Emitted when vault is set\n    event SetVault(address indexed vault);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/Proxy.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM\n * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to\n * be specified by overriding the virtual {_implementation} function.\n *\n * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a\n * different contract through the {_delegate} function.\n *\n * The success and return data of the delegated call will be returned back to the caller of the proxy.\n */\nabstract contract Proxy {\n    /**\n     * @dev Delegates the current call to `implementation`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _delegate(address implementation) internal virtual {\n        assembly {\n            // Copy msg.data. We take full control of memory in this inline assembly\n            // block because it will not return to Solidity code. We overwrite the\n            // Solidity scratch pad at memory position 0.\n            calldatacopy(0, 0, calldatasize())\n\n            // Call the implementation.\n            // out and outsize are 0 because we don't know the size yet.\n            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)\n\n            // Copy the returned data.\n            returndatacopy(0, 0, returndatasize())\n\n            switch result\n            // delegatecall returns 0 on error.\n            case 0 {\n                revert(0, returndatasize())\n            }\n            default {\n                return(0, returndatasize())\n            }\n        }\n    }\n\n    /**\n     * @dev This is a virtual function that should be overridden so it returns the address to which the fallback\n     * function and {_fallback} should delegate.\n     */\n    function _implementation() internal view virtual returns (address);\n\n    /**\n     * @dev Delegates the current call to the address returned by `_implementation()`.\n     *\n     * This function does not return to its internal call site, it will return directly to the external caller.\n     */\n    function _fallback() internal virtual {\n        _delegate(_implementation());\n    }\n\n    /**\n     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other\n     * function in the contract matches the call data.\n     */\n    fallback() external payable virtual {\n        _fallback();\n    }\n}\n"},{"file_path":"src/interfaces/queues/IDepositQueue.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"@openzeppelin/contracts/utils/structs/Checkpoints.sol\";\n\nimport \"../../libraries/FenwickTreeLibrary.sol\";\n\nimport \"../managers/IRiskManager.sol\";\nimport \"../modules/IShareModule.sol\";\nimport \"../modules/IVaultModule.sol\";\nimport \"./IQueue.sol\";\n\n/// @title IDepositQueue\n/// @notice Interface for deposit queues that manage time-delayed deposit requests with oracle-based pricing.\n/// @dev Implements request creation, cancellation, and oracle-based price batch processing.\n///\n/// # Overview\n/// A `DepositQueue` manages deposits for a specific asset with a time delay enforced by an oracle (`depositInterval`). It enforces the following invariants:\n/// 1. Each user may have only one pending deposit request at a time.\n/// 2. Each request is defined by `(amount, timestamp)`.\n/// 3. Based on oracle reports queue determines when deposit requests are processed.\n///    A report handles only those requests older than a configured `depositInterval`.\n///\n/// Once an oracle report is submitted at `reportTimestamp`, it processes all requests with `timestamp <= reportTimestamp - depositInterval`, converting asset deposits into vault shares at the reported price.\n///\n/// # User Cancellation\n/// Users can cancel pending deposit requests before they are processed. This ensures a binary lifecycle:\n/// - Either a user has a pending request they can cancel, or\n/// - The request has been executed and the user owns shares.\n///\n/// # Scalability Challenge\n/// Vaults can receive thousands of deposit requests per day. Processing each request individually is gas-inefficient.\n/// To solve this, a **Fenwick Tree** is used to maintain prefix sums of deposits per timestamp.\n///\n/// # Fenwick Tree Usage\n/// - When a user deposits `amount` at time `T`, the system records `fenwickTree[T] += amount`.\n/// - If the user cancels, then `fenwickTree[T] -= amount`.\n/// - On oracle report at time `reportTimestamp`, the system calculates:\n///   `fenwickTree.getSum(latestHandledTimestamp + 1, reportTimestamp - depositInterval)`\n///   to determine the total amount to convert into vault shares at the reported price.\n///\n/// The vault uses **lazy propagation** to calculate claimable shares per user without eagerly updating all balances in the `handleReport` processing.\n/// Shares become fully claimed on the next interaction (e.g., claim, transfer or new deposit).\n///\n/// Additionally, **timestamp compression (coordinate compression)** is used to track in FenwickTree only timestamps where actual requests were made, reducing storage overhead.\ninterface IDepositQueue is IQueue {\n    /// @notice Thrown when a user is not allowed to deposit.\n    error DepositNotAllowed();\n\n    /// @notice Thrown if a new deposit is attempted while a pending request exists.\n    error PendingRequestExists();\n\n    /// @notice Thrown when attempting to cancel a deposit request that has become claimable.\n    error ClaimableRequestExists();\n\n    /// @notice Thrown when trying to cancel a non-existent deposit request.\n    error NoPendingRequest();\n\n    /// @notice Storage layout for managing the state of a deposit queue.\n    struct DepositQueueStorage {\n        /// @dev Iterator representing the number of fully processed `timestamps`.\n        /// Each timestamp may correspond to multiple user requests.\n        uint256 handledIndices;\n        /// @dev Mapping of user address to their latest deposit request.\n        /// Each request is stored as a checkpoint with timestamp (key) and asset amount (value).\n        mapping(address account => Checkpoints.Checkpoint224) requestOf;\n        /// @dev Fenwick tree tracking cumulative asset deposits by timestamp indices.\n        /// Enables efficient range sum queries and updates for oracle processing.\n        FenwickTreeLibrary.Tree requests;\n        /// @dev Price history reported by the oracle (indexed by timestamp).\n        /// Used to convert deposited assets into vault shares.\n        Checkpoints.Trace224 prices;\n        /// @dev Total number of unclaimed requests.\n        /// Used to check that the queue can be deleted.\n        uint256 unclaimedRequests;\n    }\n\n    /// @notice Returns the number of shares that can currently be claimed by the given account.\n    /// @param account Address of the user.\n    /// @return shares Amount of claimable shares.\n    function claimableOf(address account) external view returns (uint256 shares);\n\n    /// @notice Retrieves the timestamp and asset amount for a user's pending deposit request.\n    /// @param account Address of the user.\n    /// @return timestamp When the deposit was requested.\n    /// @return assets Amount of assets deposited.\n    function requestOf(address account) external view returns (uint256 timestamp, uint256 assets);\n\n    /// @notice Returns the number of unclaimed requests.\n    /// @return unclaimedRequests Number of unclaimed requests.\n    function unclaimedRequests() external view returns (uint256 unclaimedRequests);\n\n    /// @notice Submits a new deposit request into the queue.\n    /// @dev Reverts if a previous pending (not yet claimable) request exists.\n    /// @param assets Amount of assets to deposit.\n    /// @param referral Optional referral address.\n    /// @param merkleProof Merkle proof for whitelist validation, if required.\n    function deposit(uint224 assets, address referral, bytes32[] calldata merkleProof) external payable;\n\n    /// @notice Cancels the caller's current pending deposit request.\n    /// @dev Refunds the originally deposited assets. Reverts with `ClaimableRequestExists` if the\n    /// request has already become claimable.\n    function cancelDepositRequest() external;\n\n    /// @notice Claims shares from a fulfilled deposit request for a specific account.\n    /// @param account Address for which to claim shares.\n    /// @return success Boolean indicating whether a claim was successful.\n    function claim(address account) external returns (bool success);\n\n    /// @notice Emitted when a new deposit request is submitted.\n    /// @param account The depositor's address.\n    /// @param referral Optional referral address.\n    /// @param assets Amount of assets deposited.\n    /// @param timestamp Timestamp when the request was created.\n    event DepositRequested(address indexed account, address indexed referral, uint224 assets, uint32 timestamp);\n\n    /// @notice Emitted when a pending deposit request is canceled.\n    /// @param account Address of the user who canceled the request.\n    /// @param assets Amount of assets refunded.\n    /// @param timestamp Timestamp of the original request.\n    event DepositRequestCanceled(address indexed account, uint256 assets, uint32 timestamp);\n\n    /// @notice Emitted when a deposit request is successfully claimed into shares.\n    /// @param account Address receiving the shares.\n    /// @param shares Number of shares claimed.\n    /// @param timestamp Timestamp of the original deposit request.\n    event DepositRequestClaimed(address indexed account, uint256 shares, uint32 timestamp);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n    /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\n    struct OwnableStorage {\n        address _owner;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Ownable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\n\n    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\n        assembly {\n            $.slot := OwnableStorageLocation\n        }\n    }\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    function __Ownable_init(address initialOwner) internal onlyInitializing {\n        __Ownable_init_unchained(initialOwner);\n    }\n\n    function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        OwnableStorage storage $ = _getOwnableStorage();\n        return $._owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        OwnableStorage storage $ = _getOwnableStorage();\n        address oldOwner = $._owner;\n        $._owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/Math.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.20;\n\nimport {Panic} from \"../Panic.sol\";\nimport {SafeCast} from \"./SafeCast.sol\";\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n    enum Rounding {\n        Floor, // Toward negative infinity\n        Ceil, // Toward positive infinity\n        Trunc, // Toward zero\n        Expand // Away from zero\n    }\n\n    /**\n     * @dev Return the 512-bit addition of two uint256.\n     *\n     * The result is stored in two 256 variables such that sum = high * 2²⁵⁶ + low.\n     */\n    function add512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        assembly (\"memory-safe\") {\n            low := add(a, b)\n            high := lt(low, a)\n        }\n    }\n\n    /**\n     * @dev Return the 512-bit multiplication of two uint256.\n     *\n     * The result is stored in two 256 variables such that product = high * 2²⁵⁶ + low.\n     */\n    function mul512(uint256 a, uint256 b) internal pure returns (uint256 high, uint256 low) {\n        // 512-bit multiply [high low] = x * y. Compute the product mod 2²⁵⁶ and mod 2²⁵⁶ - 1, then use\n        // the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n        // variables such that product = high * 2²⁵⁶ + low.\n        assembly (\"memory-safe\") {\n            let mm := mulmod(a, b, not(0))\n            low := mul(a, b)\n            high := sub(sub(mm, low), lt(mm, low))\n        }\n    }\n\n    /**\n     * @dev Returns the addition of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryAdd(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a + b;\n            success = c >= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, with a success flag (no overflow).\n     */\n    function trySub(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a - b;\n            success = c <= a;\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, with a success flag (no overflow).\n     */\n    function tryMul(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            uint256 c = a * b;\n            assembly (\"memory-safe\") {\n                // Only true when the multiplication doesn't overflow\n                // (c / a == b) || (a == 0)\n                success := or(eq(div(c, a), b), iszero(a))\n            }\n            // equivalent to: success ? c : 0\n            result = c * SafeCast.toUint(success);\n        }\n    }\n\n    /**\n     * @dev Returns the division of two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryDiv(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `DIV` opcode returns zero when the denominator is 0.\n                result := div(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers, with a success flag (no division by zero).\n     */\n    function tryMod(uint256 a, uint256 b) internal pure returns (bool success, uint256 result) {\n        unchecked {\n            success = b > 0;\n            assembly (\"memory-safe\") {\n                // The `MOD` opcode returns zero when the denominator is 0.\n                result := mod(a, b)\n            }\n        }\n    }\n\n    /**\n     * @dev Unsigned saturating addition, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingAdd(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryAdd(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Unsigned saturating subtraction, bounds to zero instead of overflowing.\n     */\n    function saturatingSub(uint256 a, uint256 b) internal pure returns (uint256) {\n        (, uint256 result) = trySub(a, b);\n        return result;\n    }\n\n    /**\n     * @dev Unsigned saturating multiplication, bounds to `2²⁵⁶ - 1` instead of overflowing.\n     */\n    function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        (bool success, uint256 result) = tryMul(a, b);\n        return ternary(success, result, type(uint256).max);\n    }\n\n    /**\n     * @dev Branchless ternary evaluation for `a ? b : c`. Gas costs are constant.\n     *\n     * IMPORTANT: This function may reduce bytecode size and consume less gas when used standalone.\n     * However, the compiler may optimize Solidity ternary operations (i.e. `a ? b : c`) to only compute\n     * one branch when needed, making this function more expensive.\n     */\n    function ternary(bool condition, uint256 a, uint256 b) internal pure returns (uint256) {\n        unchecked {\n            // branchless ternary works because:\n            // b ^ (a ^ b) == a\n            // b ^ 0 == b\n            return b ^ ((a ^ b) * SafeCast.toUint(condition));\n        }\n    }\n\n    /**\n     * @dev Returns the largest of two numbers.\n     */\n    function max(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a > b, a, b);\n    }\n\n    /**\n     * @dev Returns the smallest of two numbers.\n     */\n    function min(uint256 a, uint256 b) internal pure returns (uint256) {\n        return ternary(a < b, a, b);\n    }\n\n    /**\n     * @dev Returns the average of two numbers. The result is rounded towards\n     * zero.\n     */\n    function average(uint256 a, uint256 b) internal pure returns (uint256) {\n        // (a + b) / 2 can overflow.\n        return (a & b) + (a ^ b) / 2;\n    }\n\n    /**\n     * @dev Returns the ceiling of the division of two numbers.\n     *\n     * This differs from standard division with `/` in that it rounds towards infinity instead\n     * of rounding towards zero.\n     */\n    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (b == 0) {\n            // Guarantee the same behavior as in a regular Solidity division.\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n\n        // The following calculation ensures accurate ceiling division without overflow.\n        // Since a is non-zero, (a - 1) / b will not overflow.\n        // The largest possible result occurs when (a - 1) / b is type(uint256).max,\n        // but the largest value we can obtain is type(uint256).max - 1, which happens\n        // when a = type(uint256).max and b = 1.\n        unchecked {\n            return SafeCast.toUint(a > 0) * ((a - 1) / b + 1);\n        }\n    }\n\n    /**\n     * @dev Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\n     * denominator == 0.\n     *\n     * Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\n     * Uniswap Labs also under MIT license.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n\n            // Handle non-overflow cases, 256 by 256 division.\n            if (high == 0) {\n                // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n                // The surrounding unchecked block does not change this fact.\n                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n                return low / denominator;\n            }\n\n            // Make sure the result is less than 2²⁵⁶. Also prevents denominator == 0.\n            if (denominator <= high) {\n                Panic.panic(ternary(denominator == 0, Panic.DIVISION_BY_ZERO, Panic.UNDER_OVERFLOW));\n            }\n\n            ///////////////////////////////////////////////\n            // 512 by 256 division.\n            ///////////////////////////////////////////////\n\n            // Make division exact by subtracting the remainder from [high low].\n            uint256 remainder;\n            assembly (\"memory-safe\") {\n                // Compute remainder using mulmod.\n                remainder := mulmod(x, y, denominator)\n\n                // Subtract 256 bit number from 512 bit number.\n                high := sub(high, gt(remainder, low))\n                low := sub(low, remainder)\n            }\n\n            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\n            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\n\n            uint256 twos = denominator & (0 - denominator);\n            assembly (\"memory-safe\") {\n                // Divide denominator by twos.\n                denominator := div(denominator, twos)\n\n                // Divide [high low] by twos.\n                low := div(low, twos)\n\n                // Flip twos such that it is 2²⁵⁶ / twos. If twos is zero, then it becomes one.\n                twos := add(div(sub(0, twos), twos), 1)\n            }\n\n            // Shift in bits from high into low.\n            low |= high * twos;\n\n            // Invert denominator mod 2²⁵⁶. Now that denominator is an odd number, it has an inverse modulo 2²⁵⁶ such\n            // that denominator * inv ≡ 1 mod 2²⁵⁶. Compute the inverse by starting with a seed that is correct for\n            // four bits. That is, denominator * inv ≡ 1 mod 2⁴.\n            uint256 inverse = (3 * denominator) ^ 2;\n\n            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\n            // works in modular arithmetic, doubling the correct bits in each step.\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹⁶\n            inverse *= 2 - denominator * inverse; // inverse mod 2³²\n            inverse *= 2 - denominator * inverse; // inverse mod 2⁶⁴\n            inverse *= 2 - denominator * inverse; // inverse mod 2¹²⁸\n            inverse *= 2 - denominator * inverse; // inverse mod 2²⁵⁶\n\n            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n            // This will give us the correct result modulo 2²⁵⁶. Since the preconditions guarantee that the outcome is\n            // less than 2²⁵⁶, this is the final result. We don't need to compute the high bits of the result and high\n            // is no longer required.\n            result = low * inverse;\n            return result;\n        }\n    }\n\n    /**\n     * @dev Calculates x * y / denominator with full precision, following the selected rounding direction.\n     */\n    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n        return mulDiv(x, y, denominator) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0);\n    }\n\n    /**\n     * @dev Calculates floor(x * y >> n) with full precision. Throws if result overflows a uint256.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n) internal pure returns (uint256 result) {\n        unchecked {\n            (uint256 high, uint256 low) = mul512(x, y);\n            if (high >= 1 << n) {\n                Panic.panic(Panic.UNDER_OVERFLOW);\n            }\n            return (high << (256 - n)) | (low >> n);\n        }\n    }\n\n    /**\n     * @dev Calculates x * y >> n with full precision, following the selected rounding direction.\n     */\n    function mulShr(uint256 x, uint256 y, uint8 n, Rounding rounding) internal pure returns (uint256) {\n        return mulShr(x, y, n) + SafeCast.toUint(unsignedRoundsUp(rounding) && mulmod(x, y, 1 << n) > 0);\n    }\n\n    /**\n     * @dev Calculate the modular multiplicative inverse of a number in Z/nZ.\n     *\n     * If n is a prime, then Z/nZ is a field. In that case all elements are inversible, except 0.\n     * If n is not a prime, then Z/nZ is not a field, and some elements might not be inversible.\n     *\n     * If the input value is not inversible, 0 is returned.\n     *\n     * NOTE: If you know for sure that n is (big) a prime, it may be cheaper to use Fermat's little theorem and get the\n     * inverse using `Math.modExp(a, n - 2, n)`. See {invModPrime}.\n     */\n    function invMod(uint256 a, uint256 n) internal pure returns (uint256) {\n        unchecked {\n            if (n == 0) return 0;\n\n            // The inverse modulo is calculated using the Extended Euclidean Algorithm (iterative version)\n            // Used to compute integers x and y such that: ax + ny = gcd(a, n).\n            // When the gcd is 1, then the inverse of a modulo n exists and it's x.\n            // ax + ny = 1\n            // ax = 1 + (-y)n\n            // ax ≡ 1 (mod n) # x is the inverse of a modulo n\n\n            // If the remainder is 0 the gcd is n right away.\n            uint256 remainder = a % n;\n            uint256 gcd = n;\n\n            // Therefore the initial coefficients are:\n            // ax + ny = gcd(a, n) = n\n            // 0a + 1n = n\n            int256 x = 0;\n            int256 y = 1;\n\n            while (remainder != 0) {\n                uint256 quotient = gcd / remainder;\n\n                (gcd, remainder) = (\n                    // The old remainder is the next gcd to try.\n                    remainder,\n                    // Compute the next remainder.\n                    // Can't overflow given that (a % gcd) * (gcd // (a % gcd)) <= gcd\n                    // where gcd is at most n (capped to type(uint256).max)\n                    gcd - remainder * quotient\n                );\n\n                (x, y) = (\n                    // Increment the coefficient of a.\n                    y,\n                    // Decrement the coefficient of n.\n                    // Can overflow, but the result is casted to uint256 so that the\n                    // next value of y is \"wrapped around\" to a value between 0 and n - 1.\n                    x - y * int256(quotient)\n                );\n            }\n\n            if (gcd != 1) return 0; // No inverse exists.\n            return ternary(x < 0, n - uint256(-x), uint256(x)); // Wrap the result if it's negative.\n        }\n    }\n\n    /**\n     * @dev Variant of {invMod}. More efficient, but only works if `p` is known to be a prime greater than `2`.\n     *\n     * From https://en.wikipedia.org/wiki/Fermat%27s_little_theorem[Fermat's little theorem], we know that if p is\n     * prime, then `a**(p-1) ≡ 1 mod p`. As a consequence, we have `a * a**(p-2) ≡ 1 mod p`, which means that\n     * `a**(p-2)` is the modular multiplicative inverse of a in Fp.\n     *\n     * NOTE: this function does NOT check that `p` is a prime greater than `2`.\n     */\n    function invModPrime(uint256 a, uint256 p) internal view returns (uint256) {\n        unchecked {\n            return Math.modExp(a, p - 2, p);\n        }\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m)\n     *\n     * Requirements:\n     * - modulus can't be zero\n     * - underlying staticcall to precompile must succeed\n     *\n     * IMPORTANT: The result is only valid if the underlying call succeeds. When using this function, make\n     * sure the chain you're using it on supports the precompiled contract for modular exponentiation\n     * at address 0x05 as specified in https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise,\n     * the underlying function will succeed given the lack of a revert, but the result may be incorrectly\n     * interpreted as 0.\n     */\n    function modExp(uint256 b, uint256 e, uint256 m) internal view returns (uint256) {\n        (bool success, uint256 result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Returns the modular exponentiation of the specified base, exponent and modulus (b ** e % m).\n     * It includes a success flag indicating if the operation succeeded. Operation will be marked as failed if trying\n     * to operate modulo 0 or if the underlying precompile reverted.\n     *\n     * IMPORTANT: The result is only valid if the success flag is true. When using this function, make sure the chain\n     * you're using it on supports the precompiled contract for modular exponentiation at address 0x05 as specified in\n     * https://eips.ethereum.org/EIPS/eip-198[EIP-198]. Otherwise, the underlying function will succeed given the lack\n     * of a revert, but the result may be incorrectly interpreted as 0.\n     */\n    function tryModExp(uint256 b, uint256 e, uint256 m) internal view returns (bool success, uint256 result) {\n        if (m == 0) return (false, 0);\n        assembly (\"memory-safe\") {\n            let ptr := mload(0x40)\n            // | Offset    | Content    | Content (Hex)                                                      |\n            // |-----------|------------|--------------------------------------------------------------------|\n            // | 0x00:0x1f | size of b  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x20:0x3f | size of e  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x40:0x5f | size of m  | 0x0000000000000000000000000000000000000000000000000000000000000020 |\n            // | 0x60:0x7f | value of b | 0x<.............................................................b> |\n            // | 0x80:0x9f | value of e | 0x<.............................................................e> |\n            // | 0xa0:0xbf | value of m | 0x<.............................................................m> |\n            mstore(ptr, 0x20)\n            mstore(add(ptr, 0x20), 0x20)\n            mstore(add(ptr, 0x40), 0x20)\n            mstore(add(ptr, 0x60), b)\n            mstore(add(ptr, 0x80), e)\n            mstore(add(ptr, 0xa0), m)\n\n            // Given the result < m, it's guaranteed to fit in 32 bytes,\n            // so we can use the memory scratch space located at offset 0.\n            success := staticcall(gas(), 0x05, ptr, 0xc0, 0x00, 0x20)\n            result := mload(0x00)\n        }\n    }\n\n    /**\n     * @dev Variant of {modExp} that supports inputs of arbitrary length.\n     */\n    function modExp(bytes memory b, bytes memory e, bytes memory m) internal view returns (bytes memory) {\n        (bool success, bytes memory result) = tryModExp(b, e, m);\n        if (!success) {\n            Panic.panic(Panic.DIVISION_BY_ZERO);\n        }\n        return result;\n    }\n\n    /**\n     * @dev Variant of {tryModExp} that supports inputs of arbitrary length.\n     */\n    function tryModExp(\n        bytes memory b,\n        bytes memory e,\n        bytes memory m\n    ) internal view returns (bool success, bytes memory result) {\n        if (_zeroBytes(m)) return (false, new bytes(0));\n\n        uint256 mLen = m.length;\n\n        // Encode call args in result and move the free memory pointer\n        result = abi.encodePacked(b.length, e.length, mLen, b, e, m);\n\n        assembly (\"memory-safe\") {\n            let dataPtr := add(result, 0x20)\n            // Write result on top of args to avoid allocating extra memory.\n            success := staticcall(gas(), 0x05, dataPtr, mload(result), dataPtr, mLen)\n            // Overwrite the length.\n            // result.length > returndatasize() is guaranteed because returndatasize() == m.length\n            mstore(result, mLen)\n            // Set the memory pointer after the returned data.\n            mstore(0x40, add(dataPtr, mLen))\n        }\n    }\n\n    /**\n     * @dev Returns whether the provided byte array is zero.\n     */\n    function _zeroBytes(bytes memory byteArray) private pure returns (bool) {\n        for (uint256 i = 0; i < byteArray.length; ++i) {\n            if (byteArray[i] != 0) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\n     * towards zero.\n     *\n     * This method is based on Newton's method for computing square roots; the algorithm is restricted to only\n     * using integer operations.\n     */\n    function sqrt(uint256 a) internal pure returns (uint256) {\n        unchecked {\n            // Take care of easy edge cases when a == 0 or a == 1\n            if (a <= 1) {\n                return a;\n            }\n\n            // In this function, we use Newton's method to get a root of `f(x) := x² - a`. It involves building a\n            // sequence x_n that converges toward sqrt(a). For each iteration x_n, we also define the error between\n            // the current value as `ε_n = | x_n - sqrt(a) |`.\n            //\n            // For our first estimation, we consider `e` the smallest power of 2 which is bigger than the square root\n            // of the target. (i.e. `2**(e-1) ≤ sqrt(a) < 2**e`). We know that `e ≤ 128` because `(2¹²⁸)² = 2²⁵⁶` is\n            // bigger than any uint256.\n            //\n            // By noticing that\n            // `2**(e-1) ≤ sqrt(a) < 2**e → (2**(e-1))² ≤ a < (2**e)² → 2**(2*e-2) ≤ a < 2**(2*e)`\n            // we can deduce that `e - 1` is `log2(a) / 2`. We can thus compute `x_n = 2**(e-1)` using a method similar\n            // to the msb function.\n            uint256 aa = a;\n            uint256 xn = 1;\n\n            if (aa >= (1 << 128)) {\n                aa >>= 128;\n                xn <<= 64;\n            }\n            if (aa >= (1 << 64)) {\n                aa >>= 64;\n                xn <<= 32;\n            }\n            if (aa >= (1 << 32)) {\n                aa >>= 32;\n                xn <<= 16;\n            }\n            if (aa >= (1 << 16)) {\n                aa >>= 16;\n                xn <<= 8;\n            }\n            if (aa >= (1 << 8)) {\n                aa >>= 8;\n                xn <<= 4;\n            }\n            if (aa >= (1 << 4)) {\n                aa >>= 4;\n                xn <<= 2;\n            }\n            if (aa >= (1 << 2)) {\n                xn <<= 1;\n            }\n\n            // We now have x_n such that `x_n = 2**(e-1) ≤ sqrt(a) < 2**e = 2 * x_n`. This implies ε_n ≤ 2**(e-1).\n            //\n            // We can refine our estimation by noticing that the middle of that interval minimizes the error.\n            // If we move x_n to equal 2**(e-1) + 2**(e-2), then we reduce the error to ε_n ≤ 2**(e-2).\n            // This is going to be our x_0 (and ε_0)\n            xn = (3 * xn) >> 1; // ε_0 := | x_0 - sqrt(a) | ≤ 2**(e-2)\n\n            // From here, Newton's method give us:\n            // x_{n+1} = (x_n + a / x_n) / 2\n            //\n            // One should note that:\n            // x_{n+1}² - a = ((x_n + a / x_n) / 2)² - a\n            //              = ((x_n² + a) / (2 * x_n))² - a\n            //              = (x_n⁴ + 2 * a * x_n² + a²) / (4 * x_n²) - a\n            //              = (x_n⁴ + 2 * a * x_n² + a² - 4 * a * x_n²) / (4 * x_n²)\n            //              = (x_n⁴ - 2 * a * x_n² + a²) / (4 * x_n²)\n            //              = (x_n² - a)² / (2 * x_n)²\n            //              = ((x_n² - a) / (2 * x_n))²\n            //              ≥ 0\n            // Which proves that for all n ≥ 1, sqrt(a) ≤ x_n\n            //\n            // This gives us the proof of quadratic convergence of the sequence:\n            // ε_{n+1} = | x_{n+1} - sqrt(a) |\n            //         = | (x_n + a / x_n) / 2 - sqrt(a) |\n            //         = | (x_n² + a - 2*x_n*sqrt(a)) / (2 * x_n) |\n            //         = | (x_n - sqrt(a))² / (2 * x_n) |\n            //         = | ε_n² / (2 * x_n) |\n            //         = ε_n² / | (2 * x_n) |\n            //\n            // For the first iteration, we have a special case where x_0 is known:\n            // ε_1 = ε_0² / | (2 * x_0) |\n            //     ≤ (2**(e-2))² / (2 * (2**(e-1) + 2**(e-2)))\n            //     ≤ 2**(2*e-4) / (3 * 2**(e-1))\n            //     ≤ 2**(e-3) / 3\n            //     ≤ 2**(e-3-log2(3))\n            //     ≤ 2**(e-4.5)\n            //\n            // For the following iterations, we use the fact that, 2**(e-1) ≤ sqrt(a) ≤ x_n:\n            // ε_{n+1} = ε_n² / | (2 * x_n) |\n            //         ≤ (2**(e-k))² / (2 * 2**(e-1))\n            //         ≤ 2**(2*e-2*k) / 2**e\n            //         ≤ 2**(e-2*k)\n            xn = (xn + a / xn) >> 1; // ε_1 := | x_1 - sqrt(a) | ≤ 2**(e-4.5)  -- special case, see above\n            xn = (xn + a / xn) >> 1; // ε_2 := | x_2 - sqrt(a) | ≤ 2**(e-9)    -- general case with k = 4.5\n            xn = (xn + a / xn) >> 1; // ε_3 := | x_3 - sqrt(a) | ≤ 2**(e-18)   -- general case with k = 9\n            xn = (xn + a / xn) >> 1; // ε_4 := | x_4 - sqrt(a) | ≤ 2**(e-36)   -- general case with k = 18\n            xn = (xn + a / xn) >> 1; // ε_5 := | x_5 - sqrt(a) | ≤ 2**(e-72)   -- general case with k = 36\n            xn = (xn + a / xn) >> 1; // ε_6 := | x_6 - sqrt(a) | ≤ 2**(e-144)  -- general case with k = 72\n\n            // Because e ≤ 128 (as discussed during the first estimation phase), we know have reached a precision\n            // ε_6 ≤ 2**(e-144) < 1. Given we're operating on integers, then we can ensure that xn is now either\n            // sqrt(a) or sqrt(a) + 1.\n            return xn - SafeCast.toUint(xn > a / xn);\n        }\n    }\n\n    /**\n     * @dev Calculates sqrt(a), following the selected rounding direction.\n     */\n    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = sqrt(a);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && result * result < a);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // If upper 8 bits of 16-bit half set, add 8 to result\n        r |= SafeCast.toUint((x >> r) > 0xff) << 3;\n        // If upper 4 bits of 8-bit half set, add 4 to result\n        r |= SafeCast.toUint((x >> r) > 0xf) << 2;\n\n        // Shifts value right by the current result and use it as an index into this lookup table:\n        //\n        // | x (4 bits) |  index  | table[index] = MSB position |\n        // |------------|---------|-----------------------------|\n        // |    0000    |    0    |        table[0] = 0         |\n        // |    0001    |    1    |        table[1] = 0         |\n        // |    0010    |    2    |        table[2] = 1         |\n        // |    0011    |    3    |        table[3] = 1         |\n        // |    0100    |    4    |        table[4] = 2         |\n        // |    0101    |    5    |        table[5] = 2         |\n        // |    0110    |    6    |        table[6] = 2         |\n        // |    0111    |    7    |        table[7] = 2         |\n        // |    1000    |    8    |        table[8] = 3         |\n        // |    1001    |    9    |        table[9] = 3         |\n        // |    1010    |   10    |        table[10] = 3        |\n        // |    1011    |   11    |        table[11] = 3        |\n        // |    1100    |   12    |        table[12] = 3        |\n        // |    1101    |   13    |        table[13] = 3        |\n        // |    1110    |   14    |        table[14] = 3        |\n        // |    1111    |   15    |        table[15] = 3        |\n        //\n        // The lookup table is represented as a 32-byte value with the MSB positions for 0-15 in the last 16 bytes.\n        assembly (\"memory-safe\") {\n            r := or(r, byte(shr(r, x), 0x0000010102020202030303030303030300000000000000000000000000000000))\n        }\n    }\n\n    /**\n     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log2(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 10 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value) internal pure returns (uint256) {\n        uint256 result = 0;\n        unchecked {\n            if (value >= 10 ** 64) {\n                value /= 10 ** 64;\n                result += 64;\n            }\n            if (value >= 10 ** 32) {\n                value /= 10 ** 32;\n                result += 32;\n            }\n            if (value >= 10 ** 16) {\n                value /= 10 ** 16;\n                result += 16;\n            }\n            if (value >= 10 ** 8) {\n                value /= 10 ** 8;\n                result += 8;\n            }\n            if (value >= 10 ** 4) {\n                value /= 10 ** 4;\n                result += 4;\n            }\n            if (value >= 10 ** 2) {\n                value /= 10 ** 2;\n                result += 2;\n            }\n            if (value >= 10 ** 1) {\n                result += 1;\n            }\n        }\n        return result;\n    }\n\n    /**\n     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log10(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 10 ** result < value);\n        }\n    }\n\n    /**\n     * @dev Return the log in base 256 of a positive value rounded towards zero.\n     * Returns 0 if given 0.\n     *\n     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n     */\n    function log256(uint256 x) internal pure returns (uint256 r) {\n        // If value has upper 128 bits set, log2 result is at least 128\n        r = SafeCast.toUint(x > 0xffffffffffffffffffffffffffffffff) << 7;\n        // If upper 64 bits of 128-bit half set, add 64 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffffffffffff) << 6;\n        // If upper 32 bits of 64-bit half set, add 32 to result\n        r |= SafeCast.toUint((x >> r) > 0xffffffff) << 5;\n        // If upper 16 bits of 32-bit half set, add 16 to result\n        r |= SafeCast.toUint((x >> r) > 0xffff) << 4;\n        // Add 1 if upper 8 bits of 16-bit half set, and divide accumulated result by 8\n        return (r >> 3) | SafeCast.toUint((x >> r) > 0xff);\n    }\n\n    /**\n     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n     * Returns 0 if given 0.\n     */\n    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n        unchecked {\n            uint256 result = log256(value);\n            return result + SafeCast.toUint(unsignedRoundsUp(rounding) && 1 << (result << 3) < value);\n        }\n    }\n\n    /**\n     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\n     */\n    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\n        return uint8(rounding) % 2 == 1;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/structs/EnumerableSet.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.\n\npragma solidity ^0.8.20;\n\nimport {Arrays} from \"../Arrays.sol\";\n\n/**\n * @dev Library for managing\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\n * types.\n *\n * Sets have the following properties:\n *\n * - Elements are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\n * - Set can be cleared (all elements removed) in O(n).\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableSet for EnumerableSet.AddressSet;\n *\n *     // Declare a set state variable\n *     EnumerableSet.AddressSet private mySet;\n * }\n * ```\n *\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\n * and `uint256` (`UintSet`) are supported.\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableSet.\n * ====\n */\nlibrary EnumerableSet {\n    // To implement this library for multiple types with as little code\n    // repetition as possible, we write it in terms of a generic Set type with\n    // bytes32 values.\n    // The Set implementation uses private functions, and user-facing\n    // implementations (such as AddressSet) are just wrappers around the\n    // underlying Set.\n    // This means that we can only create new EnumerableSets for types that fit\n    // in bytes32.\n\n    struct Set {\n        // Storage of set values\n        bytes32[] _values;\n        // Position is the index of the value in the `values` array plus 1.\n        // Position 0 is used to mean a value is not in the set.\n        mapping(bytes32 value => uint256) _positions;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function _add(Set storage set, bytes32 value) private returns (bool) {\n        if (!_contains(set, value)) {\n            set._values.push(value);\n            // The value is stored at length-1, but we add 1 to all indexes\n            // and use 0 as a sentinel value\n            set._positions[value] = set._values.length;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\n        // We cache the value's position to prevent multiple reads from the same storage slot\n        uint256 position = set._positions[value];\n\n        if (position != 0) {\n            // Equivalent to contains(set, value)\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\n            // This modifies the order of the array, as noted in {at}.\n\n            uint256 valueIndex = position - 1;\n            uint256 lastIndex = set._values.length - 1;\n\n            if (valueIndex != lastIndex) {\n                bytes32 lastValue = set._values[lastIndex];\n\n                // Move the lastValue to the index where the value to delete is\n                set._values[valueIndex] = lastValue;\n                // Update the tracked position of the lastValue (that was just moved)\n                set._positions[lastValue] = position;\n            }\n\n            // Delete the slot where the moved value was stored\n            set._values.pop();\n\n            // Delete the tracked position for the deleted slot\n            delete set._positions[value];\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function _clear(Set storage set) private {\n        uint256 len = _length(set);\n        for (uint256 i = 0; i < len; ++i) {\n            delete set._positions[set._values[i]];\n        }\n        Arrays.unsafeSetLength(set._values, 0);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\n        return set._positions[value] != 0;\n    }\n\n    /**\n     * @dev Returns the number of values on the set. O(1).\n     */\n    function _length(Set storage set) private view returns (uint256) {\n        return set._values.length;\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\n        return set._values[index];\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function _values(Set storage set) private view returns (bytes32[] memory) {\n        return set._values;\n    }\n\n    // Bytes32Set\n\n    struct Bytes32Set {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _add(set._inner, value);\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\n        return _remove(set._inner, value);\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(Bytes32Set storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\n        return _contains(set._inner, value);\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(Bytes32Set storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\n        return _at(set._inner, index);\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressSet\n\n    struct AddressSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(AddressSet storage set, address value) internal returns (bool) {\n        return _add(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(AddressSet storage set, address value) internal returns (bool) {\n        return _remove(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(AddressSet storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(AddressSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\n        return address(uint160(uint256(_at(set._inner, index))));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(AddressSet storage set) internal view returns (address[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintSet\n\n    struct UintSet {\n        Set _inner;\n    }\n\n    /**\n     * @dev Add a value to a set. O(1).\n     *\n     * Returns true if the value was added to the set, that is if it was not\n     * already present.\n     */\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\n        return _add(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a set. O(1).\n     *\n     * Returns true if the value was removed from the set, that is if it was\n     * present.\n     */\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\n        return _remove(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Removes all the values from a set. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the set grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(UintSet storage set) internal {\n        _clear(set._inner);\n    }\n\n    /**\n     * @dev Returns true if the value is in the set. O(1).\n     */\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\n        return _contains(set._inner, bytes32(value));\n    }\n\n    /**\n     * @dev Returns the number of values in the set. O(1).\n     */\n    function length(UintSet storage set) internal view returns (uint256) {\n        return _length(set._inner);\n    }\n\n    /**\n     * @dev Returns the value stored at position `index` in the set. O(1).\n     *\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\n        return uint256(_at(set._inner, index));\n    }\n\n    /**\n     * @dev Return the entire set in an array\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function values(UintSet storage set) internal view returns (uint256[] memory) {\n        bytes32[] memory store = _values(set._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/cryptography/MerkleProof.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/cryptography/MerkleProof.sol)\n// This file was procedurally generated from scripts/generate/templates/MerkleProof.js.\n\npragma solidity ^0.8.20;\n\nimport {Hashes} from \"./Hashes.sol\";\n\n/**\n * @dev These functions deal with verification of Merkle Tree proofs.\n *\n * The tree and the proofs can be generated using our\n * https://github.com/OpenZeppelin/merkle-tree[JavaScript library].\n * You will find a quickstart guide in the readme.\n *\n * WARNING: You should avoid using leaf values that are 64 bytes long prior to\n * hashing, or use a hash function other than keccak256 for hashing leaves.\n * This is because the concatenation of a sorted pair of internal nodes in\n * the Merkle tree could be reinterpreted as a leaf value.\n * OpenZeppelin's JavaScript library generates Merkle trees that are safe\n * against this attack out of the box.\n *\n * IMPORTANT: Consider memory side-effects when using custom hashing functions\n * that access memory in an unsafe way.\n *\n * NOTE: This library supports proof verification for merkle trees built using\n * custom _commutative_ hashing functions (i.e. `H(a, b) == H(b, a)`). Proving\n * leaf inclusion in trees built using non-commutative hashing functions requires\n * additional logic that is not supported by this library.\n */\nlibrary MerkleProof {\n    /**\n     *@dev The multiproof provided is not valid.\n     */\n    error MerkleProofInvalidMultiproof();\n\n    /**\n     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n     * defined by `root`. For this, a `proof` must be provided, containing\n     * sibling hashes on the branch from the leaf to the root of the tree. Each\n     * pair of leaves and each pair of pre-images are assumed to be sorted.\n     *\n     * This version handles proofs in memory with the default hashing function.\n     */\n    function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n        return processProof(proof, leaf) == root;\n    }\n\n    /**\n     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\n     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n     * hash matches the root of the tree. When processing the proof, the pairs\n     * of leaves & pre-images are assumed to be sorted.\n     *\n     * This version handles proofs in memory with the default hashing function.\n     */\n    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {\n        bytes32 computedHash = leaf;\n        for (uint256 i = 0; i < proof.length; i++) {\n            computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]);\n        }\n        return computedHash;\n    }\n\n    /**\n     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n     * defined by `root`. For this, a `proof` must be provided, containing\n     * sibling hashes on the branch from the leaf to the root of the tree. Each\n     * pair of leaves and each pair of pre-images are assumed to be sorted.\n     *\n     * This version handles proofs in memory with a custom hashing function.\n     */\n    function verify(\n        bytes32[] memory proof,\n        bytes32 root,\n        bytes32 leaf,\n        function(bytes32, bytes32) view returns (bytes32) hasher\n    ) internal view returns (bool) {\n        return processProof(proof, leaf, hasher) == root;\n    }\n\n    /**\n     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\n     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n     * hash matches the root of the tree. When processing the proof, the pairs\n     * of leaves & pre-images are assumed to be sorted.\n     *\n     * This version handles proofs in memory with a custom hashing function.\n     */\n    function processProof(\n        bytes32[] memory proof,\n        bytes32 leaf,\n        function(bytes32, bytes32) view returns (bytes32) hasher\n    ) internal view returns (bytes32) {\n        bytes32 computedHash = leaf;\n        for (uint256 i = 0; i < proof.length; i++) {\n            computedHash = hasher(computedHash, proof[i]);\n        }\n        return computedHash;\n    }\n\n    /**\n     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n     * defined by `root`. For this, a `proof` must be provided, containing\n     * sibling hashes on the branch from the leaf to the root of the tree. Each\n     * pair of leaves and each pair of pre-images are assumed to be sorted.\n     *\n     * This version handles proofs in calldata with the default hashing function.\n     */\n    function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {\n        return processProofCalldata(proof, leaf) == root;\n    }\n\n    /**\n     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\n     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n     * hash matches the root of the tree. When processing the proof, the pairs\n     * of leaves & pre-images are assumed to be sorted.\n     *\n     * This version handles proofs in calldata with the default hashing function.\n     */\n    function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) {\n        bytes32 computedHash = leaf;\n        for (uint256 i = 0; i < proof.length; i++) {\n            computedHash = Hashes.commutativeKeccak256(computedHash, proof[i]);\n        }\n        return computedHash;\n    }\n\n    /**\n     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree\n     * defined by `root`. For this, a `proof` must be provided, containing\n     * sibling hashes on the branch from the leaf to the root of the tree. Each\n     * pair of leaves and each pair of pre-images are assumed to be sorted.\n     *\n     * This version handles proofs in calldata with a custom hashing function.\n     */\n    function verifyCalldata(\n        bytes32[] calldata proof,\n        bytes32 root,\n        bytes32 leaf,\n        function(bytes32, bytes32) view returns (bytes32) hasher\n    ) internal view returns (bool) {\n        return processProofCalldata(proof, leaf, hasher) == root;\n    }\n\n    /**\n     * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up\n     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt\n     * hash matches the root of the tree. When processing the proof, the pairs\n     * of leaves & pre-images are assumed to be sorted.\n     *\n     * This version handles proofs in calldata with a custom hashing function.\n     */\n    function processProofCalldata(\n        bytes32[] calldata proof,\n        bytes32 leaf,\n        function(bytes32, bytes32) view returns (bytes32) hasher\n    ) internal view returns (bytes32) {\n        bytes32 computedHash = leaf;\n        for (uint256 i = 0; i < proof.length; i++) {\n            computedHash = hasher(computedHash, proof[i]);\n        }\n        return computedHash;\n    }\n\n    /**\n     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by\n     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\n     *\n     * This version handles multiproofs in memory with the default hashing function.\n     *\n     * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.\n     *\n     * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.\n     * The `leaves` must be validated independently. See {processMultiProof}.\n     */\n    function multiProofVerify(\n        bytes32[] memory proof,\n        bool[] memory proofFlags,\n        bytes32 root,\n        bytes32[] memory leaves\n    ) internal pure returns (bool) {\n        return processMultiProof(proof, proofFlags, leaves) == root;\n    }\n\n    /**\n     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction\n     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another\n     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false\n     * respectively.\n     *\n     * This version handles multiproofs in memory with the default hashing function.\n     *\n     * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree\n     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the\n     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).\n     *\n     * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,\n     * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not\n     * validating the leaves elsewhere.\n     */\n    function processMultiProof(\n        bytes32[] memory proof,\n        bool[] memory proofFlags,\n        bytes32[] memory leaves\n    ) internal pure returns (bytes32 merkleRoot) {\n        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by\n        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\n        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\n        // the Merkle tree.\n        uint256 leavesLen = leaves.length;\n        uint256 proofFlagsLen = proofFlags.length;\n\n        // Check proof validity.\n        if (leavesLen + proof.length != proofFlagsLen + 1) {\n            revert MerkleProofInvalidMultiproof();\n        }\n\n        // The xxxPos values are \"pointers\" to the next value to consume in each array. All accesses are done using\n        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \"pop\".\n        bytes32[] memory hashes = new bytes32[](proofFlagsLen);\n        uint256 leafPos = 0;\n        uint256 hashPos = 0;\n        uint256 proofPos = 0;\n        // At each step, we compute the next hash using two values:\n        // - a value from the \"main queue\". If not all leaves have been consumed, we get the next leaf, otherwise we\n        //   get the next hash.\n        // - depending on the flag, either another value from the \"main queue\" (merging branches) or an element from the\n        //   `proof` array.\n        for (uint256 i = 0; i < proofFlagsLen; i++) {\n            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\n            bytes32 b = proofFlags[i]\n                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])\n                : proof[proofPos++];\n            hashes[i] = Hashes.commutativeKeccak256(a, b);\n        }\n\n        if (proofFlagsLen > 0) {\n            if (proofPos != proof.length) {\n                revert MerkleProofInvalidMultiproof();\n            }\n            unchecked {\n                return hashes[proofFlagsLen - 1];\n            }\n        } else if (leavesLen > 0) {\n            return leaves[0];\n        } else {\n            return proof[0];\n        }\n    }\n\n    /**\n     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by\n     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\n     *\n     * This version handles multiproofs in memory with a custom hashing function.\n     *\n     * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.\n     *\n     * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.\n     * The `leaves` must be validated independently. See {processMultiProof}.\n     */\n    function multiProofVerify(\n        bytes32[] memory proof,\n        bool[] memory proofFlags,\n        bytes32 root,\n        bytes32[] memory leaves,\n        function(bytes32, bytes32) view returns (bytes32) hasher\n    ) internal view returns (bool) {\n        return processMultiProof(proof, proofFlags, leaves, hasher) == root;\n    }\n\n    /**\n     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction\n     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another\n     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false\n     * respectively.\n     *\n     * This version handles multiproofs in memory with a custom hashing function.\n     *\n     * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree\n     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the\n     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).\n     *\n     * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,\n     * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not\n     * validating the leaves elsewhere.\n     */\n    function processMultiProof(\n        bytes32[] memory proof,\n        bool[] memory proofFlags,\n        bytes32[] memory leaves,\n        function(bytes32, bytes32) view returns (bytes32) hasher\n    ) internal view returns (bytes32 merkleRoot) {\n        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by\n        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\n        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\n        // the Merkle tree.\n        uint256 leavesLen = leaves.length;\n        uint256 proofFlagsLen = proofFlags.length;\n\n        // Check proof validity.\n        if (leavesLen + proof.length != proofFlagsLen + 1) {\n            revert MerkleProofInvalidMultiproof();\n        }\n\n        // The xxxPos values are \"pointers\" to the next value to consume in each array. All accesses are done using\n        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \"pop\".\n        bytes32[] memory hashes = new bytes32[](proofFlagsLen);\n        uint256 leafPos = 0;\n        uint256 hashPos = 0;\n        uint256 proofPos = 0;\n        // At each step, we compute the next hash using two values:\n        // - a value from the \"main queue\". If not all leaves have been consumed, we get the next leaf, otherwise we\n        //   get the next hash.\n        // - depending on the flag, either another value from the \"main queue\" (merging branches) or an element from the\n        //   `proof` array.\n        for (uint256 i = 0; i < proofFlagsLen; i++) {\n            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\n            bytes32 b = proofFlags[i]\n                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])\n                : proof[proofPos++];\n            hashes[i] = hasher(a, b);\n        }\n\n        if (proofFlagsLen > 0) {\n            if (proofPos != proof.length) {\n                revert MerkleProofInvalidMultiproof();\n            }\n            unchecked {\n                return hashes[proofFlagsLen - 1];\n            }\n        } else if (leavesLen > 0) {\n            return leaves[0];\n        } else {\n            return proof[0];\n        }\n    }\n\n    /**\n     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by\n     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\n     *\n     * This version handles multiproofs in calldata with the default hashing function.\n     *\n     * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.\n     *\n     * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.\n     * The `leaves` must be validated independently. See {processMultiProofCalldata}.\n     */\n    function multiProofVerifyCalldata(\n        bytes32[] calldata proof,\n        bool[] calldata proofFlags,\n        bytes32 root,\n        bytes32[] memory leaves\n    ) internal pure returns (bool) {\n        return processMultiProofCalldata(proof, proofFlags, leaves) == root;\n    }\n\n    /**\n     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction\n     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another\n     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false\n     * respectively.\n     *\n     * This version handles multiproofs in calldata with the default hashing function.\n     *\n     * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree\n     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the\n     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).\n     *\n     * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,\n     * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not\n     * validating the leaves elsewhere.\n     */\n    function processMultiProofCalldata(\n        bytes32[] calldata proof,\n        bool[] calldata proofFlags,\n        bytes32[] memory leaves\n    ) internal pure returns (bytes32 merkleRoot) {\n        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by\n        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\n        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\n        // the Merkle tree.\n        uint256 leavesLen = leaves.length;\n        uint256 proofFlagsLen = proofFlags.length;\n\n        // Check proof validity.\n        if (leavesLen + proof.length != proofFlagsLen + 1) {\n            revert MerkleProofInvalidMultiproof();\n        }\n\n        // The xxxPos values are \"pointers\" to the next value to consume in each array. All accesses are done using\n        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \"pop\".\n        bytes32[] memory hashes = new bytes32[](proofFlagsLen);\n        uint256 leafPos = 0;\n        uint256 hashPos = 0;\n        uint256 proofPos = 0;\n        // At each step, we compute the next hash using two values:\n        // - a value from the \"main queue\". If not all leaves have been consumed, we get the next leaf, otherwise we\n        //   get the next hash.\n        // - depending on the flag, either another value from the \"main queue\" (merging branches) or an element from the\n        //   `proof` array.\n        for (uint256 i = 0; i < proofFlagsLen; i++) {\n            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\n            bytes32 b = proofFlags[i]\n                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])\n                : proof[proofPos++];\n            hashes[i] = Hashes.commutativeKeccak256(a, b);\n        }\n\n        if (proofFlagsLen > 0) {\n            if (proofPos != proof.length) {\n                revert MerkleProofInvalidMultiproof();\n            }\n            unchecked {\n                return hashes[proofFlagsLen - 1];\n            }\n        } else if (leavesLen > 0) {\n            return leaves[0];\n        } else {\n            return proof[0];\n        }\n    }\n\n    /**\n     * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by\n     * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}.\n     *\n     * This version handles multiproofs in calldata with a custom hashing function.\n     *\n     * CAUTION: Not all Merkle trees admit multiproofs. See {processMultiProof} for details.\n     *\n     * NOTE: Consider the case where `root == proof[0] && leaves.length == 0` as it will return `true`.\n     * The `leaves` must be validated independently. See {processMultiProofCalldata}.\n     */\n    function multiProofVerifyCalldata(\n        bytes32[] calldata proof,\n        bool[] calldata proofFlags,\n        bytes32 root,\n        bytes32[] memory leaves,\n        function(bytes32, bytes32) view returns (bytes32) hasher\n    ) internal view returns (bool) {\n        return processMultiProofCalldata(proof, proofFlags, leaves, hasher) == root;\n    }\n\n    /**\n     * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction\n     * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another\n     * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false\n     * respectively.\n     *\n     * This version handles multiproofs in calldata with a custom hashing function.\n     *\n     * CAUTION: Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree\n     * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the\n     * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).\n     *\n     * NOTE: The _empty set_ (i.e. the case where `proof.length == 1 && leaves.length == 0`) is considered a no-op,\n     * and therefore a valid multiproof (i.e. it returns `proof[0]`). Consider disallowing this case if you're not\n     * validating the leaves elsewhere.\n     */\n    function processMultiProofCalldata(\n        bytes32[] calldata proof,\n        bool[] calldata proofFlags,\n        bytes32[] memory leaves,\n        function(bytes32, bytes32) view returns (bytes32) hasher\n    ) internal view returns (bytes32 merkleRoot) {\n        // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by\n        // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the\n        // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of\n        // the Merkle tree.\n        uint256 leavesLen = leaves.length;\n        uint256 proofFlagsLen = proofFlags.length;\n\n        // Check proof validity.\n        if (leavesLen + proof.length != proofFlagsLen + 1) {\n            revert MerkleProofInvalidMultiproof();\n        }\n\n        // The xxxPos values are \"pointers\" to the next value to consume in each array. All accesses are done using\n        // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's \"pop\".\n        bytes32[] memory hashes = new bytes32[](proofFlagsLen);\n        uint256 leafPos = 0;\n        uint256 hashPos = 0;\n        uint256 proofPos = 0;\n        // At each step, we compute the next hash using two values:\n        // - a value from the \"main queue\". If not all leaves have been consumed, we get the next leaf, otherwise we\n        //   get the next hash.\n        // - depending on the flag, either another value from the \"main queue\" (merging branches) or an element from the\n        //   `proof` array.\n        for (uint256 i = 0; i < proofFlagsLen; i++) {\n            bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++];\n            bytes32 b = proofFlags[i]\n                ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++])\n                : proof[proofPos++];\n            hashes[i] = hasher(a, b);\n        }\n\n        if (proofFlagsLen > 0) {\n            if (proofPos != proof.length) {\n                revert MerkleProofInvalidMultiproof();\n            }\n            unchecked {\n                return hashes[proofFlagsLen - 1];\n            }\n        } else if (leavesLen > 0) {\n            return leaves[0];\n        } else {\n            return proof[0];\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Errors.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of common custom errors used in multiple contracts\n *\n * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.\n * It is recommended to avoid relying on the error API for critical functionality.\n *\n * _Available since v5.1._\n */\nlibrary Errors {\n    /**\n     * @dev The ETH balance of the account is not enough to perform the operation.\n     */\n    error InsufficientBalance(uint256 balance, uint256 needed);\n\n    /**\n     * @dev A call to an address target failed. The target may have reverted.\n     */\n    error FailedCall();\n\n    /**\n     * @dev The deployment failed.\n     */\n    error FailedDeployment();\n\n    /**\n     * @dev A necessary precompile is missing.\n     */\n    error MissingPrecompile(address);\n}\n"},{"file_path":"src/interfaces/permissions/IVerifier.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts/access/IAccessControl.sol\";\nimport \"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\";\nimport \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n\nimport \"../factories/IFactoryEntity.sol\";\nimport \"./ICustomVerifier.sol\";\n\n/// @notice Interface for the Verifier contract, used to validate allowed calls via multiple verification mechanisms\ninterface IVerifier is IFactoryEntity {\n    /// @notice Thrown when a caller lacks necessary permissions\n    error Forbidden();\n\n    /// @notice Thrown when a call fails verification\n    error VerificationFailed();\n\n    /// @notice Thrown when a required value (e.g. address) is zero\n    error ZeroValue();\n\n    /// @notice Thrown when input array lengths mismatch\n    error InvalidLength();\n\n    /// @notice Thrown when attempting to allow an already allowed CompactCall\n    error CompactCallAlreadyAllowed(address who, address where, bytes4 selector);\n\n    /// @notice Thrown when attempting to disallow a non-existent CompactCall\n    error CompactCallNotFound(address who, address where, bytes4 selector);\n\n    /// @notice Represents a minimal function call format using only selector-level granularity.\n    /// @dev Used in compact verification where only caller, target, and function selector are validated.\n    struct CompactCall {\n        address who; // The address initiating the call (caller)\n        address where; // The target contract address\n        bytes4 selector; // 4-byte function selector (first 4 bytes of calldata)\n    }\n\n    /// @notice Represents a full function call with calldata and ETH value.\n    /// @dev Used in extended verification types where arguments and call value must be validated.\n    struct ExtendedCall {\n        address who; // The address initiating the call (caller)\n        address where; // The target contract address\n        uint256 value; // ETH value sent with the call\n        bytes data; // Full calldata (function selector + encoded arguments)\n    }\n\n    /// @notice Internal storage layout used by the Verifier contract.\n    /// @dev Tracks verification configuration and access control data for calls made by the vault.\n    struct VerifierStorage {\n        address vault; // The vault that owns this verifier.\n        bytes32 merkleRoot; // Root of the Merkle tree used in Merkle-based verification modes\n        EnumerableSet.Bytes32Set compactCallHashes; // Set of approved hashed CompactCall entries for ONCHAIN_COMPACT verification types\n        mapping(bytes32 => CompactCall) compactCalls; // Optional mapping to recover original CompactCall from hash\n    }\n\n    /// @notice Enum defining the method used to verify a function call authorization.\n    enum VerificationType {\n        /// @dev Compact on-chain verification.\n        /// Checks if `keccak256(abi.encode(who, where, selector))` exists in the verifier's `compactCallHashes` set.\n        ONCHAIN_COMPACT,\n        /// @dev Merkle-based verification of a compact call.\n        /// Validates a Merkle proof for `keccak256(abi.encode(who, where, selector))` against a stored Merkle root.\n        MERKLE_COMPACT,\n        /// @dev Merkle-based verification of an extended call.\n        /// Validates a Merkle proof for `keccak256(abi.encode(who, where, value, data))` against a stored Merkle root.\n        MERKLE_EXTENDED,\n        /// @dev Delegated verification via external contract.\n        /// Forwards call details `abi.encode(address customVerifier, customVerifierSpecificData)`\n        /// to a custom verifier contract implementing `ICustomVerifier`.\n        CUSTOM_VERIFIER\n    }\n\n    /// @notice Struct containing all inputs required to verify a delegated function call.\n    struct VerificationPayload {\n        /// @dev The method used to verify the delegated call.\n        VerificationType verificationType;\n        /// @dev Encoded payload to be verified, varies by verification type:\n        /// - ONCHAIN_COMPACT: empty, checking directly that `keccak256(abi.encode(who, where, selector))` is allowed\n        /// - MERKLE_COMPACT: `abi.encodePacked(keccak256(abi.encode(who, where, selector)))` to validates a Merkle proof\n        /// - MERKLE_EXTENDED: `abi.encodePacked(keccak256(abi.encode(who, where, value, data)))` to validates a Merkle proof\n        /// - CUSTOM_VERIFIER: `abi.encode(address customVerifier, customVerifierSpecificData)`\n        bytes verificationData;\n        /// @dev Merkle proof used to validate the `verificationType` and `verificationData` for MERKLE_COMPACT,\n        /// MERKLE_EXTENDED, and CUSTOM_VERIFIER types.\n        bytes32[] proof;\n    }\n\n    /// @notice Role identifier for setting Merkle root\n    function SET_MERKLE_ROOT_ROLE() external view returns (bytes32);\n\n    /// @notice Role identifier for permitted callers\n    function CALLER_ROLE() external view returns (bytes32);\n\n    /// @notice Role identifier for allowing new CompactCalls\n    function ALLOW_CALL_ROLE() external view returns (bytes32);\n\n    /// @notice Role identifier for removing CompactCalls\n    function DISALLOW_CALL_ROLE() external view returns (bytes32);\n\n    /// @notice Returns the vault associated to this Verifier contract\n    function vault() external view returns (IAccessControl);\n\n    /// @notice Returns the current Merkle root\n    function merkleRoot() external view returns (bytes32);\n\n    /// @notice Returns number of currently allowed compact calls\n    function allowedCalls() external view returns (uint256);\n\n    /// @notice Returns the compact call at a specific index\n    function allowedCallAt(uint256 index) external view returns (CompactCall memory);\n\n    /// @notice Checks if a CompactCall is explicitly allowed\n    function isAllowedCall(address who, address where, bytes calldata callData) external view returns (bool);\n\n    /// @notice Computes the hash of a CompactCall\n    function hashCall(CompactCall memory call) external pure returns (bytes32);\n\n    /// @notice Computes the hash of an ExtendedCall\n    function hashCall(ExtendedCall memory call) external pure returns (bytes32);\n\n    /// @notice Validates a function call using the provided verification payload, reverts on failure\n    function verifyCall(\n        address who,\n        address where,\n        uint256 value,\n        bytes calldata data,\n        VerificationPayload calldata verificationPayload\n    ) external view;\n\n    /// @return bool Returns whether a given call passes verification\n    function getVerificationResult(\n        address who,\n        address where,\n        uint256 value,\n        bytes calldata callData,\n        VerificationPayload calldata verificationPayload\n    ) external view returns (bool);\n\n    /// @notice Sets the Merkle root used for verification\n    function setMerkleRoot(bytes32 merkleRoot_) external;\n\n    /// @notice Adds a list of CompactCalls to the allowlist\n    function allowCalls(CompactCall[] calldata compactCalls) external;\n\n    /// @notice Removes a list of CompactCalls from the allowlist\n    function disallowCalls(CompactCall[] calldata compactCalls) external;\n\n    /// @notice Emitted when the Merkle root is set\n    event SetMerkleRoot(bytes32 merkleRoot);\n\n    /// @notice Emitted when a new CompactCall is allowed\n    event AllowCall(address who, address where, bytes4 selector);\n\n    /// @notice Emitted when a CompactCall is disallowed\n    event DisallowCall(address who, address where, bytes4 selector);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/cryptography/Hashes.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/cryptography/Hashes.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library of standard hash functions.\n *\n * _Available since v5.1._\n */\nlibrary Hashes {\n    /**\n     * @dev Commutative Keccak256 hash of a sorted pair of bytes32. Frequently used when working with merkle proofs.\n     *\n     * NOTE: Equivalent to the `standardNodeHash` in our https://github.com/OpenZeppelin/merkle-tree[JavaScript library].\n     */\n    function commutativeKeccak256(bytes32 a, bytes32 b) internal pure returns (bytes32) {\n        return a < b ? efficientKeccak256(a, b) : efficientKeccak256(b, a);\n    }\n\n    /**\n     * @dev Implementation of keccak256(abi.encode(a, b)) that doesn't allocate or expand memory.\n     */\n    function efficientKeccak256(bytes32 a, bytes32 b) internal pure returns (bytes32 value) {\n        assembly (\"memory-safe\") {\n            mstore(0x00, a)\n            mstore(0x20, b)\n            value := keccak256(0x00, 0x40)\n        }\n    }\n}\n"},{"file_path":"src/interfaces/factories/IFactoryEntity.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\n/// @title IFactoryEntity\ninterface IFactoryEntity {\n    /// @notice Initializes the factory-created entity with arbitrary initialization data.\n    /// @param initParams The initialization parameters.\n    function initialize(bytes calldata initParams) external;\n\n    /// @notice Emitted once the entity has been initialized.\n    /// @param initParams The initialization parameters.\n    event Initialized(bytes initParams);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/utils/ContextUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n    function __Context_init() internal onlyInitializing {\n    }\n\n    function __Context_init_unchained() internal onlyInitializing {\n    }\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC1967.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n */\ninterface IERC1967 {\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Emitted when the beacon is changed.\n     */\n    event BeaconUpgraded(address indexed beacon);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/Ownable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\n\npragma solidity ^0.8.20;\n\nimport {Context} from \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * The initial owner is set to the address provided by the deployer. This can\n * later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n    address private _owner;\n\n    /**\n     * @dev The caller account is not authorized to perform an operation.\n     */\n    error OwnableUnauthorizedAccount(address account);\n\n    /**\n     * @dev The owner is not a valid owner account. (eg. `address(0)`)\n     */\n    error OwnableInvalidOwner(address owner);\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\n     */\n    constructor(address initialOwner) {\n        if (initialOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(initialOwner);\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        _checkOwner();\n        _;\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view virtual returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if the sender is not the owner.\n     */\n    function _checkOwner() internal view virtual {\n        if (owner() != _msgSender()) {\n            revert OwnableUnauthorizedAccount(_msgSender());\n        }\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby disabling any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public virtual onlyOwner {\n        _transferOwnership(address(0));\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public virtual onlyOwner {\n        if (newOwner == address(0)) {\n            revert OwnableInvalidOwner(address(0));\n        }\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Internal function without access restriction.\n     */\n    function _transferOwnership(address newOwner) internal virtual {\n        address oldOwner = _owner;\n        _owner = newOwner;\n        emit OwnershipTransferred(oldOwner, newOwner);\n    }\n}\n"},{"file_path":"src/interfaces/modules/IShareModule.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../factories/IFactory.sol\";\nimport \"../hooks/IRedeemHook.sol\";\nimport \"../managers/IFeeManager.sol\";\nimport \"../managers/IShareManager.sol\";\nimport \"../oracles/IOracle.sol\";\nimport \"../queues/IDepositQueue.sol\";\nimport \"../queues/IQueue.sol\";\nimport \"../queues/IRedeemQueue.sol\";\nimport \"./IBaseModule.sol\";\n\n/// @title IShareModule\n/// @notice Manages user-facing interactions with the vault via deposit/redeem queues, hooks, and share accounting.\n/// @dev Coordinates oracle report handling, hook invocation, fee calculation, and queue lifecycle.\ninterface IShareModule is IBaseModule {\n    /// @notice Thrown when an unsupported asset is used for queue creation.\n    error UnsupportedAsset(address asset);\n\n    /// @notice Thrown when the number of queues exceeds the allowed system-wide maximum.\n    error QueueLimitReached();\n\n    /// @notice Thrown when an operation is attempted with a zero-value parameter.\n    error ZeroValue();\n\n    /// @dev Storage structure for the ShareModule.\n    struct ShareModuleStorage {\n        address shareManager; // Address of the ShareManager responsible for minting/burning shares\n        address feeManager; // Address of the FeeManager that calculates and collects protocol fees\n        address oracle; // Address of the Oracle\n        address defaultDepositHook; // Optional hook that is called by default after DepositQueue requests are processed\n        address defaultRedeemHook; // Optional hook that is called by default before RedeemQueue requests are processed\n        uint256 queueCount; // Total number of queues across all assets\n        uint256 queueLimit; // Maximum number of queues allowed in the system\n        mapping(address => address) customHooks; // Optional queue-specific hooks\n        mapping(address => bool) isDepositQueue; // Whether the queue is a deposit queue\n        mapping(address => bool) isPausedQueue; // Whether queue operations are currently paused\n        mapping(address => EnumerableSet.AddressSet) queues; // Mapping of asset to its associated queues\n        EnumerableSet.AddressSet assets; // Set of all supported assets with queues\n    }\n\n    /// @notice Role identifier for managing per-queue and default hooks\n    function SET_HOOK_ROLE() external view returns (bytes32);\n\n    /// @notice Role identifier for creating new queues\n    function CREATE_QUEUE_ROLE() external view returns (bytes32);\n\n    /// @notice Role identifier for changing the active/paused status of queues\n    function SET_QUEUE_STATUS_ROLE() external view returns (bytes32);\n\n    /// @notice Role identifier for modifying the global queue limit\n    function SET_QUEUE_LIMIT_ROLE() external view returns (bytes32);\n\n    /// @notice Role identifier for removing existing queues\n    function REMOVE_QUEUE_ROLE() external view returns (bytes32);\n\n    /// @notice Returns the ShareManager used for minting and burning shares\n    function shareManager() external view returns (IShareManager);\n\n    /// @notice Returns the FeeManager contract used for fee calculations\n    function feeManager() external view returns (IFeeManager);\n\n    /// @notice Returns the Oracle contract used for handling reports and managing supported assets.\n    function oracle() external view returns (IOracle);\n\n    /// @notice Returns the factory used for deploying deposit queues\n    function depositQueueFactory() external view returns (IFactory);\n\n    /// @notice Returns the factory used for deploying redeem queues\n    function redeemQueueFactory() external view returns (IFactory);\n\n    /// @notice Returns total number of distinct assets with queues\n    function getAssetCount() external view returns (uint256);\n\n    /// @notice Returns the address of the asset at the given index\n    function assetAt(uint256 index) external view returns (address);\n\n    /// @notice Returns whether the given asset is associated with any queues\n    function hasAsset(address asset) external view returns (bool);\n\n    /// @notice Returns whether the given queue is registered\n    function hasQueue(address queue) external view returns (bool);\n\n    /// @notice Returns whether the given queue is a deposit queue\n    function isDepositQueue(address queue) external view returns (bool);\n\n    /// @notice Returns whether the given queue is currently paused\n    function isPausedQueue(address queue) external view returns (bool);\n\n    /// @notice Returns number of queues associated with a given asset\n    function getQueueCount(address asset) external view returns (uint256);\n\n    /// @notice Returns the total number of queues across all assets\n    function getQueueCount() external view returns (uint256);\n\n    /// @notice Returns the queue at the given index for the specified asset\n    function queueAt(address asset, uint256 index) external view returns (address);\n\n    /// @notice Returns the hook assigned to a queue (customHook or defaultHook as a fallback)\n    function getHook(address queue) external view returns (address hook);\n\n    /// @notice Returns the default hook for deposit queues\n    function defaultDepositHook() external view returns (address);\n\n    /// @notice Returns the default hook for redeem queues\n    function defaultRedeemHook() external view returns (address);\n\n    /// @notice Returns the current global queue limit\n    function queueLimit() external view returns (uint256);\n\n    /// @notice Returns the total number of claimable shares for a given user\n    function claimableSharesOf(address account) external view returns (uint256 shares);\n\n    /// @notice Called by redeem queues to check the amount of assets available for instant withdrawal\n    function getLiquidAssets() external view returns (uint256);\n\n    /// @notice Claims all claimable shares from deposit queues for the specified account\n    function claimShares(address account) external;\n\n    /// @notice Assigns a custom hook contract to a specific queue\n    function setCustomHook(address queue, address hook) external;\n\n    /// @notice Sets the global default deposit hook\n    function setDefaultDepositHook(address hook) external;\n\n    /// @notice Sets the global default redeem hook\n    function setDefaultRedeemHook(address hook) external;\n\n    /// @notice Creates a new deposit or redeem queue for a given asset\n    function createQueue(uint256 version, bool isDepositQueue, address owner, address asset, bytes calldata data)\n        external;\n\n    /// @notice Removes a queue from the system if its `canBeRemoved()` function returns true\n    function removeQueue(address queue) external;\n\n    /// @notice Sets the maximum number of allowed queues across the module\n    function setQueueLimit(uint256 limit) external;\n\n    /// @notice Pauses or resumes a queue's operation\n    function setQueueStatus(address queue, bool isPaused) external;\n\n    /// @notice Invokes a queue's hook (also transfers assets to the queue for redeem queues)\n    function callHook(uint256 assets) external;\n\n    /// @notice Handles an oracle price report, distributes fees and calls internal hooks\n    function handleReport(address asset, uint224 priceD18, uint32 depositTimestamp, uint32 redeemTimestamp) external;\n\n    /// @notice Emitted when a user successfully claims shares from deposit queues\n    event SharesClaimed(address indexed account);\n\n    /// @notice Emitted when a queue-specific custom hook is updated\n    event CustomHookSet(address indexed queue, address indexed hook);\n\n    /// @notice Emitted when a new queue is created\n    event QueueCreated(address indexed queue, address indexed asset, bool isDepositQueue);\n\n    /// @notice Emitted when a queue is removed\n    event QueueRemoved(address indexed queue, address indexed asset);\n\n    /// @notice Emitted after a queue hook is successfully called\n    event HookCalled(address indexed queue, address indexed asset, uint256 assets, address hook);\n\n    /// @notice Emitted when the global queue limit is updated\n    event QueueLimitSet(uint256 limit);\n\n    /// @notice Emitted when a queue's paused status changes\n    event SetQueueStatus(address indexed queue, bool indexed isPaused);\n\n    /// @notice Emitted when a new default hook is configured\n    event DefaultHookSet(address indexed hook, bool isDepositHook);\n\n    /// @notice Emitted after processing a price report and fee distribution\n    event ReportHandled(\n        address indexed asset, uint224 indexed priceD18, uint32 depositTimestamp, uint32 redeemTimestamp, uint256 fees\n    );\n}\n"},{"file_path":"src/interfaces/modules/IACLModule.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../permissions/IMellowACL.sol\";\nimport \"./IBaseModule.sol\";\n\n/// @notice Interface for the ACLModule, implements IMellowACL\ninterface IACLModule is IMellowACL {\n    /// @notice Thrown when a zero address is provided\n    error ZeroAddress();\n\n    /// @notice Thrown when an unauthorized caller attempts a restricted operation\n    error Forbidden();\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/access/IAccessControl.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (access/IAccessControl.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev External interface of AccessControl declared to support ERC-165 detection.\n */\ninterface IAccessControl {\n    /**\n     * @dev The `account` is missing a role.\n     */\n    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n    /**\n     * @dev The caller of a function is not the expected one.\n     *\n     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n     */\n    error AccessControlBadConfirmation();\n\n    /**\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n     *\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n     * {RoleAdminChanged} not being emitted to signal this.\n     */\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n    /**\n     * @dev Emitted when `account` is granted `role`.\n     *\n     * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).\n     * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.\n     */\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Emitted when `account` is revoked `role`.\n     *\n     * `sender` is the account that originated the contract call:\n     *   - if using `revokeRole`, it is the admin role bearer\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\n     */\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) external view returns (bool);\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function grantRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     */\n    function revokeRole(bytes32 role, address account) external;\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) external;\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Panic.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Panic.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Helper library for emitting standardized panic codes.\n *\n * ```solidity\n * contract Example {\n *      using Panic for uint256;\n *\n *      // Use any of the declared internal constants\n *      function foo() { Panic.GENERIC.panic(); }\n *\n *      // Alternatively\n *      function foo() { Panic.panic(Panic.GENERIC); }\n * }\n * ```\n *\n * Follows the list from https://github.com/ethereum/solidity/blob/v0.8.24/libsolutil/ErrorCodes.h[libsolutil].\n *\n * _Available since v5.1._\n */\n// slither-disable-next-line unused-state\nlibrary Panic {\n    /// @dev generic / unspecified error\n    uint256 internal constant GENERIC = 0x00;\n    /// @dev used by the assert() builtin\n    uint256 internal constant ASSERT = 0x01;\n    /// @dev arithmetic underflow or overflow\n    uint256 internal constant UNDER_OVERFLOW = 0x11;\n    /// @dev division or modulo by zero\n    uint256 internal constant DIVISION_BY_ZERO = 0x12;\n    /// @dev enum conversion error\n    uint256 internal constant ENUM_CONVERSION_ERROR = 0x21;\n    /// @dev invalid encoding in storage\n    uint256 internal constant STORAGE_ENCODING_ERROR = 0x22;\n    /// @dev empty array pop\n    uint256 internal constant EMPTY_ARRAY_POP = 0x31;\n    /// @dev array out of bounds access\n    uint256 internal constant ARRAY_OUT_OF_BOUNDS = 0x32;\n    /// @dev resource error (too large allocation or too large array)\n    uint256 internal constant RESOURCE_ERROR = 0x41;\n    /// @dev calling invalid internal function\n    uint256 internal constant INVALID_INTERNAL_FUNCTION = 0x51;\n\n    /// @dev Reverts with a panic code. Recommended to use with\n    /// the internal constants with predefined codes.\n    function panic(uint256 code) internal pure {\n        assembly (\"memory-safe\") {\n            mstore(0x00, 0x4e487b71)\n            mstore(0x20, code)\n            revert(0x1c, 0x24)\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/beacon/IBeacon.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {UpgradeableBeacon} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/access/AccessControlUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"@openzeppelin/contracts/access/IAccessControl.sol\";\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"../utils/introspection/ERC165Upgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n *     require(hasRole(MY_ROLE, msg.sender));\n *     ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable {\n    struct RoleData {\n        mapping(address account => bool) hasRole;\n        bytes32 adminRole;\n    }\n\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n\n    /// @custom:storage-location erc7201:openzeppelin.storage.AccessControl\n    struct AccessControlStorage {\n        mapping(bytes32 role => RoleData) _roles;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.AccessControl\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant AccessControlStorageLocation = 0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800;\n\n    function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) {\n        assembly {\n            $.slot := AccessControlStorageLocation\n        }\n    }\n\n    /**\n     * @dev Modifier that checks that an account has a specific role. Reverts\n     * with an {AccessControlUnauthorizedAccount} error including the required role.\n     */\n    modifier onlyRole(bytes32 role) {\n        _checkRole(role);\n        _;\n    }\n\n    function __AccessControl_init() internal onlyInitializing {\n    }\n\n    function __AccessControl_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n    }\n\n    /**\n     * @dev Returns `true` if `account` has been granted `role`.\n     */\n    function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        return $._roles[role].hasRole[account];\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n     */\n    function _checkRole(bytes32 role) internal view virtual {\n        _checkRole(role, _msgSender());\n    }\n\n    /**\n     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n     * is missing `role`.\n     */\n    function _checkRole(bytes32 role, address account) internal view virtual {\n        if (!hasRole(role, account)) {\n            revert AccessControlUnauthorizedAccount(account, role);\n        }\n    }\n\n    /**\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\n     * {revokeRole}.\n     *\n     * To change a role's admin, use {_setRoleAdmin}.\n     */\n    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        return $._roles[role].adminRole;\n    }\n\n    /**\n     * @dev Grants `role` to `account`.\n     *\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _grantRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from `account`.\n     *\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\n     *\n     * Requirements:\n     *\n     * - the caller must have ``role``'s admin role.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n        _revokeRole(role, account);\n    }\n\n    /**\n     * @dev Revokes `role` from the calling account.\n     *\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\n     * purpose is to provide a mechanism for accounts to lose their privileges\n     * if they are compromised (such as when a trusted device is misplaced).\n     *\n     * If the calling account had been revoked `role`, emits a {RoleRevoked}\n     * event.\n     *\n     * Requirements:\n     *\n     * - the caller must be `callerConfirmation`.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n        if (callerConfirmation != _msgSender()) {\n            revert AccessControlBadConfirmation();\n        }\n\n        _revokeRole(role, callerConfirmation);\n    }\n\n    /**\n     * @dev Sets `adminRole` as ``role``'s admin role.\n     *\n     * Emits a {RoleAdminChanged} event.\n     */\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        bytes32 previousAdminRole = getRoleAdmin(role);\n        $._roles[role].adminRole = adminRole;\n        emit RoleAdminChanged(role, previousAdminRole, adminRole);\n    }\n\n    /**\n     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleGranted} event.\n     */\n    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        if (!hasRole(role, account)) {\n            $._roles[role].hasRole[account] = true;\n            emit RoleGranted(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.\n     *\n     * Internal function without access restriction.\n     *\n     * May emit a {RoleRevoked} event.\n     */\n    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n        AccessControlStorage storage $ = _getAccessControlStorage();\n        if (hasRole(role, account)) {\n            $._roles[role].hasRole[account] = false;\n            emit RoleRevoked(role, account, _msgSender());\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol)\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow\n * checks.\n *\n * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can\n * easily result in undesired exploitation or bugs, since developers usually\n * assume that overflows raise errors. `SafeCast` restores this intuition by\n * reverting the transaction when such an operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeCast {\n    /**\n     * @dev Value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\n\n    /**\n     * @dev An int value doesn't fit in an uint of `bits` size.\n     */\n    error SafeCastOverflowedIntToUint(int256 value);\n\n    /**\n     * @dev Value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\n\n    /**\n     * @dev An uint value doesn't fit in an int of `bits` size.\n     */\n    error SafeCastOverflowedUintToInt(uint256 value);\n\n    /**\n     * @dev Returns the downcasted uint248 from uint256, reverting on\n     * overflow (when the input is greater than largest uint248).\n     *\n     * Counterpart to Solidity's `uint248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toUint248(uint256 value) internal pure returns (uint248) {\n        if (value > type(uint248).max) {\n            revert SafeCastOverflowedUintDowncast(248, value);\n        }\n        return uint248(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint240 from uint256, reverting on\n     * overflow (when the input is greater than largest uint240).\n     *\n     * Counterpart to Solidity's `uint240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toUint240(uint256 value) internal pure returns (uint240) {\n        if (value > type(uint240).max) {\n            revert SafeCastOverflowedUintDowncast(240, value);\n        }\n        return uint240(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint232 from uint256, reverting on\n     * overflow (when the input is greater than largest uint232).\n     *\n     * Counterpart to Solidity's `uint232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toUint232(uint256 value) internal pure returns (uint232) {\n        if (value > type(uint232).max) {\n            revert SafeCastOverflowedUintDowncast(232, value);\n        }\n        return uint232(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint224 from uint256, reverting on\n     * overflow (when the input is greater than largest uint224).\n     *\n     * Counterpart to Solidity's `uint224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toUint224(uint256 value) internal pure returns (uint224) {\n        if (value > type(uint224).max) {\n            revert SafeCastOverflowedUintDowncast(224, value);\n        }\n        return uint224(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint216 from uint256, reverting on\n     * overflow (when the input is greater than largest uint216).\n     *\n     * Counterpart to Solidity's `uint216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toUint216(uint256 value) internal pure returns (uint216) {\n        if (value > type(uint216).max) {\n            revert SafeCastOverflowedUintDowncast(216, value);\n        }\n        return uint216(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint208 from uint256, reverting on\n     * overflow (when the input is greater than largest uint208).\n     *\n     * Counterpart to Solidity's `uint208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toUint208(uint256 value) internal pure returns (uint208) {\n        if (value > type(uint208).max) {\n            revert SafeCastOverflowedUintDowncast(208, value);\n        }\n        return uint208(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint200 from uint256, reverting on\n     * overflow (when the input is greater than largest uint200).\n     *\n     * Counterpart to Solidity's `uint200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toUint200(uint256 value) internal pure returns (uint200) {\n        if (value > type(uint200).max) {\n            revert SafeCastOverflowedUintDowncast(200, value);\n        }\n        return uint200(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint192 from uint256, reverting on\n     * overflow (when the input is greater than largest uint192).\n     *\n     * Counterpart to Solidity's `uint192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toUint192(uint256 value) internal pure returns (uint192) {\n        if (value > type(uint192).max) {\n            revert SafeCastOverflowedUintDowncast(192, value);\n        }\n        return uint192(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint184 from uint256, reverting on\n     * overflow (when the input is greater than largest uint184).\n     *\n     * Counterpart to Solidity's `uint184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toUint184(uint256 value) internal pure returns (uint184) {\n        if (value > type(uint184).max) {\n            revert SafeCastOverflowedUintDowncast(184, value);\n        }\n        return uint184(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint176 from uint256, reverting on\n     * overflow (when the input is greater than largest uint176).\n     *\n     * Counterpart to Solidity's `uint176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toUint176(uint256 value) internal pure returns (uint176) {\n        if (value > type(uint176).max) {\n            revert SafeCastOverflowedUintDowncast(176, value);\n        }\n        return uint176(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint168 from uint256, reverting on\n     * overflow (when the input is greater than largest uint168).\n     *\n     * Counterpart to Solidity's `uint168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toUint168(uint256 value) internal pure returns (uint168) {\n        if (value > type(uint168).max) {\n            revert SafeCastOverflowedUintDowncast(168, value);\n        }\n        return uint168(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint160 from uint256, reverting on\n     * overflow (when the input is greater than largest uint160).\n     *\n     * Counterpart to Solidity's `uint160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toUint160(uint256 value) internal pure returns (uint160) {\n        if (value > type(uint160).max) {\n            revert SafeCastOverflowedUintDowncast(160, value);\n        }\n        return uint160(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint152 from uint256, reverting on\n     * overflow (when the input is greater than largest uint152).\n     *\n     * Counterpart to Solidity's `uint152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toUint152(uint256 value) internal pure returns (uint152) {\n        if (value > type(uint152).max) {\n            revert SafeCastOverflowedUintDowncast(152, value);\n        }\n        return uint152(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint144 from uint256, reverting on\n     * overflow (when the input is greater than largest uint144).\n     *\n     * Counterpart to Solidity's `uint144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toUint144(uint256 value) internal pure returns (uint144) {\n        if (value > type(uint144).max) {\n            revert SafeCastOverflowedUintDowncast(144, value);\n        }\n        return uint144(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint136 from uint256, reverting on\n     * overflow (when the input is greater than largest uint136).\n     *\n     * Counterpart to Solidity's `uint136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toUint136(uint256 value) internal pure returns (uint136) {\n        if (value > type(uint136).max) {\n            revert SafeCastOverflowedUintDowncast(136, value);\n        }\n        return uint136(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint128 from uint256, reverting on\n     * overflow (when the input is greater than largest uint128).\n     *\n     * Counterpart to Solidity's `uint128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toUint128(uint256 value) internal pure returns (uint128) {\n        if (value > type(uint128).max) {\n            revert SafeCastOverflowedUintDowncast(128, value);\n        }\n        return uint128(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint120 from uint256, reverting on\n     * overflow (when the input is greater than largest uint120).\n     *\n     * Counterpart to Solidity's `uint120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toUint120(uint256 value) internal pure returns (uint120) {\n        if (value > type(uint120).max) {\n            revert SafeCastOverflowedUintDowncast(120, value);\n        }\n        return uint120(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint112 from uint256, reverting on\n     * overflow (when the input is greater than largest uint112).\n     *\n     * Counterpart to Solidity's `uint112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toUint112(uint256 value) internal pure returns (uint112) {\n        if (value > type(uint112).max) {\n            revert SafeCastOverflowedUintDowncast(112, value);\n        }\n        return uint112(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint104 from uint256, reverting on\n     * overflow (when the input is greater than largest uint104).\n     *\n     * Counterpart to Solidity's `uint104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toUint104(uint256 value) internal pure returns (uint104) {\n        if (value > type(uint104).max) {\n            revert SafeCastOverflowedUintDowncast(104, value);\n        }\n        return uint104(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint96 from uint256, reverting on\n     * overflow (when the input is greater than largest uint96).\n     *\n     * Counterpart to Solidity's `uint96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toUint96(uint256 value) internal pure returns (uint96) {\n        if (value > type(uint96).max) {\n            revert SafeCastOverflowedUintDowncast(96, value);\n        }\n        return uint96(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint88 from uint256, reverting on\n     * overflow (when the input is greater than largest uint88).\n     *\n     * Counterpart to Solidity's `uint88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toUint88(uint256 value) internal pure returns (uint88) {\n        if (value > type(uint88).max) {\n            revert SafeCastOverflowedUintDowncast(88, value);\n        }\n        return uint88(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint80 from uint256, reverting on\n     * overflow (when the input is greater than largest uint80).\n     *\n     * Counterpart to Solidity's `uint80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toUint80(uint256 value) internal pure returns (uint80) {\n        if (value > type(uint80).max) {\n            revert SafeCastOverflowedUintDowncast(80, value);\n        }\n        return uint80(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint72 from uint256, reverting on\n     * overflow (when the input is greater than largest uint72).\n     *\n     * Counterpart to Solidity's `uint72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toUint72(uint256 value) internal pure returns (uint72) {\n        if (value > type(uint72).max) {\n            revert SafeCastOverflowedUintDowncast(72, value);\n        }\n        return uint72(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint64 from uint256, reverting on\n     * overflow (when the input is greater than largest uint64).\n     *\n     * Counterpart to Solidity's `uint64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toUint64(uint256 value) internal pure returns (uint64) {\n        if (value > type(uint64).max) {\n            revert SafeCastOverflowedUintDowncast(64, value);\n        }\n        return uint64(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint56 from uint256, reverting on\n     * overflow (when the input is greater than largest uint56).\n     *\n     * Counterpart to Solidity's `uint56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toUint56(uint256 value) internal pure returns (uint56) {\n        if (value > type(uint56).max) {\n            revert SafeCastOverflowedUintDowncast(56, value);\n        }\n        return uint56(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint48 from uint256, reverting on\n     * overflow (when the input is greater than largest uint48).\n     *\n     * Counterpart to Solidity's `uint48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toUint48(uint256 value) internal pure returns (uint48) {\n        if (value > type(uint48).max) {\n            revert SafeCastOverflowedUintDowncast(48, value);\n        }\n        return uint48(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint40 from uint256, reverting on\n     * overflow (when the input is greater than largest uint40).\n     *\n     * Counterpart to Solidity's `uint40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toUint40(uint256 value) internal pure returns (uint40) {\n        if (value > type(uint40).max) {\n            revert SafeCastOverflowedUintDowncast(40, value);\n        }\n        return uint40(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint32 from uint256, reverting on\n     * overflow (when the input is greater than largest uint32).\n     *\n     * Counterpart to Solidity's `uint32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toUint32(uint256 value) internal pure returns (uint32) {\n        if (value > type(uint32).max) {\n            revert SafeCastOverflowedUintDowncast(32, value);\n        }\n        return uint32(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint24 from uint256, reverting on\n     * overflow (when the input is greater than largest uint24).\n     *\n     * Counterpart to Solidity's `uint24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toUint24(uint256 value) internal pure returns (uint24) {\n        if (value > type(uint24).max) {\n            revert SafeCastOverflowedUintDowncast(24, value);\n        }\n        return uint24(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint16 from uint256, reverting on\n     * overflow (when the input is greater than largest uint16).\n     *\n     * Counterpart to Solidity's `uint16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toUint16(uint256 value) internal pure returns (uint16) {\n        if (value > type(uint16).max) {\n            revert SafeCastOverflowedUintDowncast(16, value);\n        }\n        return uint16(value);\n    }\n\n    /**\n     * @dev Returns the downcasted uint8 from uint256, reverting on\n     * overflow (when the input is greater than largest uint8).\n     *\n     * Counterpart to Solidity's `uint8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toUint8(uint256 value) internal pure returns (uint8) {\n        if (value > type(uint8).max) {\n            revert SafeCastOverflowedUintDowncast(8, value);\n        }\n        return uint8(value);\n    }\n\n    /**\n     * @dev Converts a signed int256 into an unsigned uint256.\n     *\n     * Requirements:\n     *\n     * - input must be greater than or equal to 0.\n     */\n    function toUint256(int256 value) internal pure returns (uint256) {\n        if (value < 0) {\n            revert SafeCastOverflowedIntToUint(value);\n        }\n        return uint256(value);\n    }\n\n    /**\n     * @dev Returns the downcasted int248 from int256, reverting on\n     * overflow (when the input is less than smallest int248 or\n     * greater than largest int248).\n     *\n     * Counterpart to Solidity's `int248` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 248 bits\n     */\n    function toInt248(int256 value) internal pure returns (int248 downcasted) {\n        downcasted = int248(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(248, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int240 from int256, reverting on\n     * overflow (when the input is less than smallest int240 or\n     * greater than largest int240).\n     *\n     * Counterpart to Solidity's `int240` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 240 bits\n     */\n    function toInt240(int256 value) internal pure returns (int240 downcasted) {\n        downcasted = int240(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(240, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int232 from int256, reverting on\n     * overflow (when the input is less than smallest int232 or\n     * greater than largest int232).\n     *\n     * Counterpart to Solidity's `int232` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 232 bits\n     */\n    function toInt232(int256 value) internal pure returns (int232 downcasted) {\n        downcasted = int232(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(232, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int224 from int256, reverting on\n     * overflow (when the input is less than smallest int224 or\n     * greater than largest int224).\n     *\n     * Counterpart to Solidity's `int224` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 224 bits\n     */\n    function toInt224(int256 value) internal pure returns (int224 downcasted) {\n        downcasted = int224(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(224, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int216 from int256, reverting on\n     * overflow (when the input is less than smallest int216 or\n     * greater than largest int216).\n     *\n     * Counterpart to Solidity's `int216` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 216 bits\n     */\n    function toInt216(int256 value) internal pure returns (int216 downcasted) {\n        downcasted = int216(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(216, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int208 from int256, reverting on\n     * overflow (when the input is less than smallest int208 or\n     * greater than largest int208).\n     *\n     * Counterpart to Solidity's `int208` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 208 bits\n     */\n    function toInt208(int256 value) internal pure returns (int208 downcasted) {\n        downcasted = int208(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(208, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int200 from int256, reverting on\n     * overflow (when the input is less than smallest int200 or\n     * greater than largest int200).\n     *\n     * Counterpart to Solidity's `int200` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 200 bits\n     */\n    function toInt200(int256 value) internal pure returns (int200 downcasted) {\n        downcasted = int200(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(200, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int192 from int256, reverting on\n     * overflow (when the input is less than smallest int192 or\n     * greater than largest int192).\n     *\n     * Counterpart to Solidity's `int192` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 192 bits\n     */\n    function toInt192(int256 value) internal pure returns (int192 downcasted) {\n        downcasted = int192(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(192, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int184 from int256, reverting on\n     * overflow (when the input is less than smallest int184 or\n     * greater than largest int184).\n     *\n     * Counterpart to Solidity's `int184` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 184 bits\n     */\n    function toInt184(int256 value) internal pure returns (int184 downcasted) {\n        downcasted = int184(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(184, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int176 from int256, reverting on\n     * overflow (when the input is less than smallest int176 or\n     * greater than largest int176).\n     *\n     * Counterpart to Solidity's `int176` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 176 bits\n     */\n    function toInt176(int256 value) internal pure returns (int176 downcasted) {\n        downcasted = int176(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(176, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int168 from int256, reverting on\n     * overflow (when the input is less than smallest int168 or\n     * greater than largest int168).\n     *\n     * Counterpart to Solidity's `int168` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 168 bits\n     */\n    function toInt168(int256 value) internal pure returns (int168 downcasted) {\n        downcasted = int168(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(168, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int160 from int256, reverting on\n     * overflow (when the input is less than smallest int160 or\n     * greater than largest int160).\n     *\n     * Counterpart to Solidity's `int160` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 160 bits\n     */\n    function toInt160(int256 value) internal pure returns (int160 downcasted) {\n        downcasted = int160(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(160, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int152 from int256, reverting on\n     * overflow (when the input is less than smallest int152 or\n     * greater than largest int152).\n     *\n     * Counterpart to Solidity's `int152` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 152 bits\n     */\n    function toInt152(int256 value) internal pure returns (int152 downcasted) {\n        downcasted = int152(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(152, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int144 from int256, reverting on\n     * overflow (when the input is less than smallest int144 or\n     * greater than largest int144).\n     *\n     * Counterpart to Solidity's `int144` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 144 bits\n     */\n    function toInt144(int256 value) internal pure returns (int144 downcasted) {\n        downcasted = int144(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(144, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int136 from int256, reverting on\n     * overflow (when the input is less than smallest int136 or\n     * greater than largest int136).\n     *\n     * Counterpart to Solidity's `int136` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 136 bits\n     */\n    function toInt136(int256 value) internal pure returns (int136 downcasted) {\n        downcasted = int136(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(136, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int128 from int256, reverting on\n     * overflow (when the input is less than smallest int128 or\n     * greater than largest int128).\n     *\n     * Counterpart to Solidity's `int128` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 128 bits\n     */\n    function toInt128(int256 value) internal pure returns (int128 downcasted) {\n        downcasted = int128(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(128, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int120 from int256, reverting on\n     * overflow (when the input is less than smallest int120 or\n     * greater than largest int120).\n     *\n     * Counterpart to Solidity's `int120` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 120 bits\n     */\n    function toInt120(int256 value) internal pure returns (int120 downcasted) {\n        downcasted = int120(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(120, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int112 from int256, reverting on\n     * overflow (when the input is less than smallest int112 or\n     * greater than largest int112).\n     *\n     * Counterpart to Solidity's `int112` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 112 bits\n     */\n    function toInt112(int256 value) internal pure returns (int112 downcasted) {\n        downcasted = int112(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(112, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int104 from int256, reverting on\n     * overflow (when the input is less than smallest int104 or\n     * greater than largest int104).\n     *\n     * Counterpart to Solidity's `int104` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 104 bits\n     */\n    function toInt104(int256 value) internal pure returns (int104 downcasted) {\n        downcasted = int104(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(104, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int96 from int256, reverting on\n     * overflow (when the input is less than smallest int96 or\n     * greater than largest int96).\n     *\n     * Counterpart to Solidity's `int96` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 96 bits\n     */\n    function toInt96(int256 value) internal pure returns (int96 downcasted) {\n        downcasted = int96(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(96, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int88 from int256, reverting on\n     * overflow (when the input is less than smallest int88 or\n     * greater than largest int88).\n     *\n     * Counterpart to Solidity's `int88` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 88 bits\n     */\n    function toInt88(int256 value) internal pure returns (int88 downcasted) {\n        downcasted = int88(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(88, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int80 from int256, reverting on\n     * overflow (when the input is less than smallest int80 or\n     * greater than largest int80).\n     *\n     * Counterpart to Solidity's `int80` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 80 bits\n     */\n    function toInt80(int256 value) internal pure returns (int80 downcasted) {\n        downcasted = int80(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(80, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int72 from int256, reverting on\n     * overflow (when the input is less than smallest int72 or\n     * greater than largest int72).\n     *\n     * Counterpart to Solidity's `int72` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 72 bits\n     */\n    function toInt72(int256 value) internal pure returns (int72 downcasted) {\n        downcasted = int72(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(72, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int64 from int256, reverting on\n     * overflow (when the input is less than smallest int64 or\n     * greater than largest int64).\n     *\n     * Counterpart to Solidity's `int64` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 64 bits\n     */\n    function toInt64(int256 value) internal pure returns (int64 downcasted) {\n        downcasted = int64(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(64, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int56 from int256, reverting on\n     * overflow (when the input is less than smallest int56 or\n     * greater than largest int56).\n     *\n     * Counterpart to Solidity's `int56` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 56 bits\n     */\n    function toInt56(int256 value) internal pure returns (int56 downcasted) {\n        downcasted = int56(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(56, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int48 from int256, reverting on\n     * overflow (when the input is less than smallest int48 or\n     * greater than largest int48).\n     *\n     * Counterpart to Solidity's `int48` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 48 bits\n     */\n    function toInt48(int256 value) internal pure returns (int48 downcasted) {\n        downcasted = int48(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(48, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int40 from int256, reverting on\n     * overflow (when the input is less than smallest int40 or\n     * greater than largest int40).\n     *\n     * Counterpart to Solidity's `int40` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 40 bits\n     */\n    function toInt40(int256 value) internal pure returns (int40 downcasted) {\n        downcasted = int40(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(40, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int32 from int256, reverting on\n     * overflow (when the input is less than smallest int32 or\n     * greater than largest int32).\n     *\n     * Counterpart to Solidity's `int32` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 32 bits\n     */\n    function toInt32(int256 value) internal pure returns (int32 downcasted) {\n        downcasted = int32(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(32, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int24 from int256, reverting on\n     * overflow (when the input is less than smallest int24 or\n     * greater than largest int24).\n     *\n     * Counterpart to Solidity's `int24` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 24 bits\n     */\n    function toInt24(int256 value) internal pure returns (int24 downcasted) {\n        downcasted = int24(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(24, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int16 from int256, reverting on\n     * overflow (when the input is less than smallest int16 or\n     * greater than largest int16).\n     *\n     * Counterpart to Solidity's `int16` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 16 bits\n     */\n    function toInt16(int256 value) internal pure returns (int16 downcasted) {\n        downcasted = int16(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(16, value);\n        }\n    }\n\n    /**\n     * @dev Returns the downcasted int8 from int256, reverting on\n     * overflow (when the input is less than smallest int8 or\n     * greater than largest int8).\n     *\n     * Counterpart to Solidity's `int8` operator.\n     *\n     * Requirements:\n     *\n     * - input must fit into 8 bits\n     */\n    function toInt8(int256 value) internal pure returns (int8 downcasted) {\n        downcasted = int8(value);\n        if (downcasted != value) {\n            revert SafeCastOverflowedIntDowncast(8, value);\n        }\n    }\n\n    /**\n     * @dev Converts an unsigned uint256 into a signed int256.\n     *\n     * Requirements:\n     *\n     * - input must be less than or equal to maxInt256.\n     */\n    function toInt256(uint256 value) internal pure returns (int256) {\n        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\n        if (value > uint256(type(int256).max)) {\n            revert SafeCastOverflowedUintToInt(value);\n        }\n        return int256(value);\n    }\n\n    /**\n     * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump.\n     */\n    function toUint(bool b) internal pure returns (uint256 u) {\n        assembly (\"memory-safe\") {\n            u := iszero(iszero(b))\n        }\n    }\n}\n"},{"file_path":"src/interfaces/permissions/ICustomVerifier.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\n/// @notice Interface for external/custom verification logic\n/// @dev Allows plug-in modules to define arbitrary logic for verifying function calls.\n///      Used with `VerificationType.CUSTOM_VERIFIER` in the main Verifier contract.\ninterface ICustomVerifier {\n    /// @notice Verifies whether the given call is permitted using custom logic\n    /// @param who               Address attempting the call\n    /// @param where             Target contract the call is directed to\n    /// @param value             ETH value sent with the call\n    /// @param callData          Full calldata of the intended call\n    /// @param verificationData  Extra data provided by the caller to support verification logic\n    /// @return isValid          True if the call is considered valid, false otherwise\n    function verifyCall(\n        address who,\n        address where,\n        uint256 value,\n        bytes calldata callData,\n        bytes calldata verificationData\n    ) external view returns (bool);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[ERC].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721Receiver.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @title ERC-721 token receiver interface\n * @dev Interface for any contract that wants to support safeTransfers\n * from ERC-721 asset contracts.\n */\ninterface IERC721Receiver {\n    /**\n     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\n     * by `operator` from `from`, this function is called.\n     *\n     * It must return its Solidity selector to confirm the token transfer.\n     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be\n     * reverted.\n     *\n     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\n     */\n    function onERC721Received(\n        address operator,\n        address from,\n        uint256 tokenId,\n        bytes calldata data\n    ) external returns (bytes4);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/ERC165Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165 {\n    function __ERC165_init() internal onlyInitializing {\n    }\n\n    function __ERC165_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     */\n    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n        return interfaceId == type(IERC165).interfaceId;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Comparators.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Comparators.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides a set of functions to compare values.\n *\n * _Available since v5.1._\n */\nlibrary Comparators {\n    function lt(uint256 a, uint256 b) internal pure returns (bool) {\n        return a < b;\n    }\n\n    function gt(uint256 a, uint256 b) internal pure returns (bool) {\n        return a > b;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/StorageSlot.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct Int256Slot {\n        int256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"},{"file_path":"src/interfaces/modules/ISubvaultModule.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../factories/IFactory.sol\";\n\n/// @title ISubvaultModule\n/// @notice Interface for a Subvault module used in modular vault architecture.\n/// @dev A Subvault is a child vault that holds assets and can release them to its parent vault upon request.\n/// Each Subvault is isolated and may integrate with external protocols through its own Verifier & CallModule, enabling\n/// fine-grained delegation of liquidity while maintaining separation between subvaults.\ninterface ISubvaultModule {\n    /// @notice Reverts when a caller is not the associated vault.\n    error NotVault();\n\n    /// @notice Storage laylout of ISubvaultModule.\n    /// @dev Stores the address of the parent vault that has permission to pull assets.\n    struct SubvaultModuleStorage {\n        address vault;\n    }\n\n    /// @notice Returns the address of the parent vault contract.\n    /// @return address The vault address allowed to interact with this subvault.\n    function vault() external view returns (address);\n\n    /// @notice Transfers a specified amount of an asset to the vault.\n    /// @dev Can only be called by the parent vault.\n    /// @param asset Address of the ERC20 token or native ETH.\n    /// @param value Amount of the asset to transfer.\n    function pullAssets(address asset, uint256 value) external;\n\n    /// @notice Emitted when assets are pulled from the subvault to the vault.\n    /// @param asset Address of the asset that was pulled.\n    /// @param to Recipient address (must be the vault).\n    /// @param value Amount of the asset that was pulled.\n    event AssetsPulled(address indexed asset, address indexed to, uint256 value);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/structs/Checkpoints.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/structs/Checkpoints.sol)\n// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.\n\npragma solidity ^0.8.20;\n\nimport {Math} from \"../math/Math.sol\";\n\n/**\n * @dev This library defines the `Trace*` struct, for checkpointing values as they change at different points in\n * time, and later looking up past values by block number. See {Votes} as an example.\n *\n * To create a history of checkpoints define a variable type `Checkpoints.Trace*` in your contract, and store a new\n * checkpoint for the current transaction block using the {push} function.\n */\nlibrary Checkpoints {\n    /**\n     * @dev A value was attempted to be inserted on a past checkpoint.\n     */\n    error CheckpointUnorderedInsertion();\n\n    struct Trace224 {\n        Checkpoint224[] _checkpoints;\n    }\n\n    struct Checkpoint224 {\n        uint32 _key;\n        uint224 _value;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.\n     *\n     * Returns previous value and new value.\n     *\n     * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint32).max` key set will disable the\n     * library.\n     */\n    function push(\n        Trace224 storage self,\n        uint32 key,\n        uint224 value\n    ) internal returns (uint224 oldValue, uint224 newValue) {\n        return _insert(self._checkpoints, key, value);\n    }\n\n    /**\n     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\n     * there is none.\n     */\n    function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\n    }\n\n    /**\n     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\n     * if there is none.\n     */\n    function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\n     * if there is none.\n     *\n     * NOTE: This is a variant of {upperLookup} that is optimised to find \"recent\" checkpoint (checkpoints with high\n     * keys).\n     */\n    function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {\n        uint256 len = self._checkpoints.length;\n\n        uint256 low = 0;\n        uint256 high = len;\n\n        if (len > 5) {\n            uint256 mid = len - Math.sqrt(len);\n            if (key < _unsafeAccess(self._checkpoints, mid)._key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n     */\n    function latest(Trace224 storage self) internal view returns (uint224) {\n        uint256 pos = self._checkpoints.length;\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n     * in the most recent checkpoint.\n     */\n    function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {\n        uint256 pos = self._checkpoints.length;\n        if (pos == 0) {\n            return (false, 0, 0);\n        } else {\n            Checkpoint224 storage ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n            return (true, ckpt._key, ckpt._value);\n        }\n    }\n\n    /**\n     * @dev Returns the number of checkpoints.\n     */\n    function length(Trace224 storage self) internal view returns (uint256) {\n        return self._checkpoints.length;\n    }\n\n    /**\n     * @dev Returns checkpoint at given position.\n     */\n    function at(Trace224 storage self, uint32 pos) internal view returns (Checkpoint224 memory) {\n        return self._checkpoints[pos];\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n     * or by updating the last one.\n     */\n    function _insert(\n        Checkpoint224[] storage self,\n        uint32 key,\n        uint224 value\n    ) private returns (uint224 oldValue, uint224 newValue) {\n        uint256 pos = self.length;\n\n        if (pos > 0) {\n            Checkpoint224 storage last = _unsafeAccess(self, pos - 1);\n            uint32 lastKey = last._key;\n            uint224 lastValue = last._value;\n\n            // Checkpoint keys must be non-decreasing.\n            if (lastKey > key) {\n                revert CheckpointUnorderedInsertion();\n            }\n\n            // Update or push new checkpoint\n            if (lastKey == key) {\n                last._value = value;\n            } else {\n                self.push(Checkpoint224({_key: key, _value: value}));\n            }\n            return (lastValue, value);\n        } else {\n            self.push(Checkpoint224({_key: key, _value: value}));\n            return (0, value);\n        }\n    }\n\n    /**\n     * @dev Return the index of the first (oldest) checkpoint with key strictly bigger than the search key, or `high`\n     * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\n     * `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _upperBinaryLookup(\n        Checkpoint224[] storage self,\n        uint32 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n            if (_unsafeAccess(self, mid)._key > key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Return the index of the first (oldest) checkpoint with key greater or equal than the search key, or `high`\n     * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\n     * `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _lowerBinaryLookup(\n        Checkpoint224[] storage self,\n        uint32 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n            if (_unsafeAccess(self, mid)._key < key) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n     */\n    function _unsafeAccess(\n        Checkpoint224[] storage self,\n        uint256 pos\n    ) private pure returns (Checkpoint224 storage result) {\n        assembly {\n            mstore(0, self.slot)\n            result.slot := add(keccak256(0, 0x20), pos)\n        }\n    }\n\n    struct Trace208 {\n        Checkpoint208[] _checkpoints;\n    }\n\n    struct Checkpoint208 {\n        uint48 _key;\n        uint208 _value;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into a Trace208 so that it is stored as the checkpoint.\n     *\n     * Returns previous value and new value.\n     *\n     * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint48).max` key set will disable the\n     * library.\n     */\n    function push(\n        Trace208 storage self,\n        uint48 key,\n        uint208 value\n    ) internal returns (uint208 oldValue, uint208 newValue) {\n        return _insert(self._checkpoints, key, value);\n    }\n\n    /**\n     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\n     * there is none.\n     */\n    function lowerLookup(Trace208 storage self, uint48 key) internal view returns (uint208) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\n    }\n\n    /**\n     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\n     * if there is none.\n     */\n    function upperLookup(Trace208 storage self, uint48 key) internal view returns (uint208) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\n     * if there is none.\n     *\n     * NOTE: This is a variant of {upperLookup} that is optimised to find \"recent\" checkpoint (checkpoints with high\n     * keys).\n     */\n    function upperLookupRecent(Trace208 storage self, uint48 key) internal view returns (uint208) {\n        uint256 len = self._checkpoints.length;\n\n        uint256 low = 0;\n        uint256 high = len;\n\n        if (len > 5) {\n            uint256 mid = len - Math.sqrt(len);\n            if (key < _unsafeAccess(self._checkpoints, mid)._key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n     */\n    function latest(Trace208 storage self) internal view returns (uint208) {\n        uint256 pos = self._checkpoints.length;\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n     * in the most recent checkpoint.\n     */\n    function latestCheckpoint(Trace208 storage self) internal view returns (bool exists, uint48 _key, uint208 _value) {\n        uint256 pos = self._checkpoints.length;\n        if (pos == 0) {\n            return (false, 0, 0);\n        } else {\n            Checkpoint208 storage ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n            return (true, ckpt._key, ckpt._value);\n        }\n    }\n\n    /**\n     * @dev Returns the number of checkpoints.\n     */\n    function length(Trace208 storage self) internal view returns (uint256) {\n        return self._checkpoints.length;\n    }\n\n    /**\n     * @dev Returns checkpoint at given position.\n     */\n    function at(Trace208 storage self, uint32 pos) internal view returns (Checkpoint208 memory) {\n        return self._checkpoints[pos];\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n     * or by updating the last one.\n     */\n    function _insert(\n        Checkpoint208[] storage self,\n        uint48 key,\n        uint208 value\n    ) private returns (uint208 oldValue, uint208 newValue) {\n        uint256 pos = self.length;\n\n        if (pos > 0) {\n            Checkpoint208 storage last = _unsafeAccess(self, pos - 1);\n            uint48 lastKey = last._key;\n            uint208 lastValue = last._value;\n\n            // Checkpoint keys must be non-decreasing.\n            if (lastKey > key) {\n                revert CheckpointUnorderedInsertion();\n            }\n\n            // Update or push new checkpoint\n            if (lastKey == key) {\n                last._value = value;\n            } else {\n                self.push(Checkpoint208({_key: key, _value: value}));\n            }\n            return (lastValue, value);\n        } else {\n            self.push(Checkpoint208({_key: key, _value: value}));\n            return (0, value);\n        }\n    }\n\n    /**\n     * @dev Return the index of the first (oldest) checkpoint with key strictly bigger than the search key, or `high`\n     * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\n     * `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _upperBinaryLookup(\n        Checkpoint208[] storage self,\n        uint48 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n            if (_unsafeAccess(self, mid)._key > key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Return the index of the first (oldest) checkpoint with key greater or equal than the search key, or `high`\n     * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\n     * `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _lowerBinaryLookup(\n        Checkpoint208[] storage self,\n        uint48 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n            if (_unsafeAccess(self, mid)._key < key) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n     */\n    function _unsafeAccess(\n        Checkpoint208[] storage self,\n        uint256 pos\n    ) private pure returns (Checkpoint208 storage result) {\n        assembly {\n            mstore(0, self.slot)\n            result.slot := add(keccak256(0, 0x20), pos)\n        }\n    }\n\n    struct Trace160 {\n        Checkpoint160[] _checkpoints;\n    }\n\n    struct Checkpoint160 {\n        uint96 _key;\n        uint160 _value;\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.\n     *\n     * Returns previous value and new value.\n     *\n     * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint96).max` key set will disable the\n     * library.\n     */\n    function push(\n        Trace160 storage self,\n        uint96 key,\n        uint160 value\n    ) internal returns (uint160 oldValue, uint160 newValue) {\n        return _insert(self._checkpoints, key, value);\n    }\n\n    /**\n     * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\n     * there is none.\n     */\n    function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\n    }\n\n    /**\n     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\n     * if there is none.\n     */\n    function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\n        uint256 len = self._checkpoints.length;\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\n     * if there is none.\n     *\n     * NOTE: This is a variant of {upperLookup} that is optimised to find \"recent\" checkpoint (checkpoints with high\n     * keys).\n     */\n    function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {\n        uint256 len = self._checkpoints.length;\n\n        uint256 low = 0;\n        uint256 high = len;\n\n        if (len > 5) {\n            uint256 mid = len - Math.sqrt(len);\n            if (key < _unsafeAccess(self._checkpoints, mid)._key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\n\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\n     */\n    function latest(Trace160 storage self) internal view returns (uint160) {\n        uint256 pos = self._checkpoints.length;\n        return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\n    }\n\n    /**\n     * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\n     * in the most recent checkpoint.\n     */\n    function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {\n        uint256 pos = self._checkpoints.length;\n        if (pos == 0) {\n            return (false, 0, 0);\n        } else {\n            Checkpoint160 storage ckpt = _unsafeAccess(self._checkpoints, pos - 1);\n            return (true, ckpt._key, ckpt._value);\n        }\n    }\n\n    /**\n     * @dev Returns the number of checkpoints.\n     */\n    function length(Trace160 storage self) internal view returns (uint256) {\n        return self._checkpoints.length;\n    }\n\n    /**\n     * @dev Returns checkpoint at given position.\n     */\n    function at(Trace160 storage self, uint32 pos) internal view returns (Checkpoint160 memory) {\n        return self._checkpoints[pos];\n    }\n\n    /**\n     * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\n     * or by updating the last one.\n     */\n    function _insert(\n        Checkpoint160[] storage self,\n        uint96 key,\n        uint160 value\n    ) private returns (uint160 oldValue, uint160 newValue) {\n        uint256 pos = self.length;\n\n        if (pos > 0) {\n            Checkpoint160 storage last = _unsafeAccess(self, pos - 1);\n            uint96 lastKey = last._key;\n            uint160 lastValue = last._value;\n\n            // Checkpoint keys must be non-decreasing.\n            if (lastKey > key) {\n                revert CheckpointUnorderedInsertion();\n            }\n\n            // Update or push new checkpoint\n            if (lastKey == key) {\n                last._value = value;\n            } else {\n                self.push(Checkpoint160({_key: key, _value: value}));\n            }\n            return (lastValue, value);\n        } else {\n            self.push(Checkpoint160({_key: key, _value: value}));\n            return (0, value);\n        }\n    }\n\n    /**\n     * @dev Return the index of the first (oldest) checkpoint with key strictly bigger than the search key, or `high`\n     * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\n     * `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _upperBinaryLookup(\n        Checkpoint160[] storage self,\n        uint96 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n            if (_unsafeAccess(self, mid)._key > key) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Return the index of the first (oldest) checkpoint with key greater or equal than the search key, or `high`\n     * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\n     * `high`.\n     *\n     * WARNING: `high` should not be greater than the array's length.\n     */\n    function _lowerBinaryLookup(\n        Checkpoint160[] storage self,\n        uint96 key,\n        uint256 low,\n        uint256 high\n    ) private view returns (uint256) {\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n            if (_unsafeAccess(self, mid)._key < key) {\n                low = mid + 1;\n            } else {\n                high = mid;\n            }\n        }\n        return high;\n    }\n\n    /**\n     * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\n     */\n    function _unsafeAccess(\n        Checkpoint160[] storage self,\n        uint256 pos\n    ) private pure returns (Checkpoint160 storage result) {\n        assembly {\n            mstore(0, self.slot)\n            result.slot := add(keccak256(0, 0x20), pos)\n        }\n    }\n}\n"},{"file_path":"src/interfaces/managers/IRiskManager.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\n\nimport \"@openzeppelin/contracts/utils/math/SafeCast.sol\";\nimport \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n\nimport \"../factories/IFactoryEntity.sol\";\n\nimport \"../modules/IACLModule.sol\";\nimport \"../modules/IShareModule.sol\";\nimport \"../modules/IVaultModule.sol\";\nimport \"../oracles/IOracle.sol\";\n\n/// @notice Interface for the RiskManager contract\n/// @dev Handles vault and subvault balance limits, pending asset tracking, and asset permissioning\ninterface IRiskManager is IFactoryEntity {\n    /// @notice Thrown when the caller lacks appropriate permission\n    error Forbidden();\n\n    /// @notice Thrown when a price report is flagged as suspicious, or has not been set yet.\n    error InvalidReport();\n\n    /// @notice Thrown when attempting to allow an already allowed asset\n    error AlreadyAllowedAsset(address asset);\n\n    /// @notice Thrown when attempting to disallow or use a non-allowed asset\n    error NotAllowedAsset(address asset);\n\n    /// @notice Thrown when a vault or subvault exceeds its configured limit\n    error LimitExceeded(int256 newValue, int256 maxValue);\n\n    /// @notice Thrown when a given address is not recognized as a valid subvault\n    error NotSubvault(address subvault);\n\n    /// @notice Thrown when a zero address is passed as a parameter\n    error ZeroValue();\n\n    /// @notice Tracks current and maximum balance for a vault or subvault\n    struct State {\n        int256 balance; // Current approximate shares held\n        int256 limit; // Maximum allowable approximate shares\n    }\n\n    /// @notice Storage layout for RiskManager.\n    struct RiskManagerStorage {\n        address vault; // Address of the Vault associated with this risk manager.\n        State vaultState; // Tracks the share balance and limit for the Vault.\n        int256 pendingBalance;\n        /// Cumulative approximate share balance from all pending requests in all deposit queues. Used to track unprocessed inflows.\n        mapping(address asset => int256) pendingAssets; // Pending inflow amount per asset.\n        mapping(address asset => int256) pendingShares; // Pending inflow amount in shares per asset converted by the last oracle report.\n        mapping(address subvault => State) subvaultStates; // Share state tracking for each connected subvault.\n        mapping(address subvault => EnumerableSet.AddressSet) allowedAssets; // List of assets that each subvault is allowed to interact with.\n    }\n\n    /// @notice Reverts if the given subvault is not valid for the vault\n    function requireValidSubvault(address vault_, address subvault) external view;\n\n    /// @notice Returns the address of the Vault\n    function vault() external view returns (address);\n\n    /// @notice Returns the approximate share balance and the share limit limit of the vault.\n    function vaultState() external view returns (State memory);\n\n    /// @notice Returns the pending share balance across all assets and deposit queues.\n    function pendingBalance() external view returns (int256);\n\n    /// @notice Returns the pending asset value for a specific asset\n    function pendingAssets(address asset) external view returns (int256);\n\n    /// @notice Returns the pending shares equivalent of a specific asset converted by the last oracle report for the given asset.\n    function pendingShares(address asset) external view returns (int256);\n\n    /// @notice Returns the approximate balance and the limit of a specific subvault\n    function subvaultState(address subvault) external view returns (State memory);\n\n    /// @notice Returns number of assets allowed for a given subvault\n    function allowedAssets(address subvault) external view returns (uint256);\n\n    /// @notice Returns the allowed asset at a given index for a subvault\n    function allowedAssetAt(address subvault, uint256 index) external view returns (address);\n\n    /// @notice Checks if an asset is allowed for the specified subvault\n    function isAllowedAsset(address subvault, address asset) external view returns (bool);\n\n    /// @notice Converts an asset amount into its equivalent share representation by the last oracle report\n    /// @param asset Asset being valued\n    /// @param value Amount in asset units (can be positive or negative)\n    /// @return shares Share amount\n    function convertToShares(address asset, int256 value) external view returns (int256 shares);\n\n    /// @notice Returns the maximum amount that can be deposited into a subvault for a specific asset\n    function maxDeposit(address subvault, address asset) external view returns (uint256 limit);\n\n    /// @notice Modifies the vault's internal balance by a signed delta (in asset terms)\n    function modifyVaultBalance(address asset, int256 delta) external;\n\n    /// @notice Modifies a subvault's internal balance by a signed delta (in asset terms)\n    function modifySubvaultBalance(address subvault, address asset, int256 delta) external;\n\n    /// @notice Sets the maximum allowable approximate (soft) balance for the entire vault in shares\n    function setVaultLimit(int256 limit) external;\n\n    /// @notice Sets the maximum allowable approximate (soft) balance for a specific subvault\n    function setSubvaultLimit(address subvault, int256 limit) external;\n\n    /// @notice Allows specific assets to be used in a subvault\n    function allowSubvaultAssets(address subvault, address[] calldata assets) external;\n\n    /// @notice Disallows specific assets from being used in a subvault\n    function disallowSubvaultAssets(address subvault, address[] calldata assets) external;\n\n    /// @notice Modifies the vault's pending balances by a signed delta (in asset terms)\n    function modifyPendingAssets(address asset, int256 change) external;\n\n    /// @notice Sets the vault address this RiskManager is associated with\n    function setVault(address vault_) external;\n\n    /// @notice Emitted when a limit is set for a specific subvault\n    event SetSubvaultLimit(address indexed subvault, int256 limit);\n\n    /// @notice Emitted when the vault limit is updated\n    event SetVaultLimit(int256 limit);\n\n    /// @notice Emitted when assets are newly allowed for a subvault\n    event AllowSubvaultAssets(address indexed subvault, address[] assets);\n\n    /// @notice Emitted when assets are disallowed from a subvault\n    event DisallowSubvaultAssets(address indexed subvault, address[] assets);\n\n    /// @notice Emitted when pending asset balances are updated\n    event ModifyPendingAssets(\n        address indexed asset, int256 change, int256 pendingAssetsAfter, int256 pendingSharesAfter\n    );\n\n    /// @notice Emitted when the vault balance is changed\n    event ModifyVaultBalance(address indexed asset, int256 shares, int256 newBalance);\n\n    /// @notice Emitted when a subvault's balance is changed\n    event ModifySubvaultBalance(address indexed subvault, address indexed asset, int256 change, int256 newBalance);\n\n    /// @notice Emitted when the associated vault address is set\n    event SetVault(address indexed vault);\n}\n"},{"file_path":"src/interfaces/managers/IFeeManager.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../factories/IFactoryEntity.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\n\n/// @notice Interface for the FeeManager contract\n/// @dev Handles deposit, redeem, performance, and protocol fees for vaults, and tracks per-vault price/timestamp states\ninterface IFeeManager is IFactoryEntity {\n    /// @notice Thrown when a required address is zero\n    error ZeroAddress();\n\n    /// @notice Thrown when the sum of all fees exceeds 100% (1e6 in D6 precision)\n    error InvalidFees(uint24 depositFeeD6, uint24 redeemFeeD6, uint24 performanceFeeD6, uint24 protocolFeeD6);\n\n    /// @notice Thrown when trying to overwrite a vault's base asset that was already set\n    error BaseAssetAlreadySet(address vault, address baseAsset);\n\n    /// @notice Storage layout used internally by FeeManager\n    struct FeeManagerStorage {\n        address feeRecipient; // Address that collects all fee shares\n        uint24 depositFeeD6; // Deposit fee in 6 decimals (e.g. 10000 = 1%)\n        uint24 redeemFeeD6; // Redeem fee in 6 decimals\n        uint24 performanceFeeD6; // Performance fee applied on price increase (6 decimals)\n        uint24 protocolFeeD6; // Protocol fee applied over time (6 decimals annualized)\n        mapping(address vault => uint256) timestamps; // Last update timestamp for protocol fee accrual\n        mapping(address vault => uint256) minPriceD18; // Lowests price seen for performance fee trigger (price * assets = shares)\n        mapping(address vault => address) baseAsset; // Base asset used to evaluate price-based fees\n    }\n\n    /// @notice Returns the current fee recipient address\n    function feeRecipient() external view returns (address);\n\n    /// @notice Returns the configured deposit fee (in D6 precision)\n    function depositFeeD6() external view returns (uint24);\n\n    /// @notice Returns the configured redeem fee (in D6 precision)\n    function redeemFeeD6() external view returns (uint24);\n\n    /// @notice Returns the configured performance fee (in D6 precision)\n    function performanceFeeD6() external view returns (uint24);\n\n    /// @notice Returns the configured protocol fee (in D6 precision per year)\n    function protocolFeeD6() external view returns (uint24);\n\n    /// @notice Returns the last recorded timestamp for a given vault (used for protocol fee accrual)\n    function timestamps(address vault) external view returns (uint256);\n\n    /// @notice Returns the last recorded min price for a vault's base asset (used for performance fee)\n    function minPriceD18(address vault) external view returns (uint256);\n\n    /// @notice Returns the base asset configured for a vault\n    function baseAsset(address vault) external view returns (address);\n\n    /// @notice Calculates the deposit fee in shares based on the amount\n    /// @param amount Number of shares being deposited\n    /// @return Fee in shares to be deducted\n    function calculateDepositFee(uint256 amount) external view returns (uint256);\n\n    /// @notice Calculates the redeem fee in shares based on the amount\n    /// @param amount Number of shares being redeemed\n    /// @return Fee in shares to be deducted\n    function calculateRedeemFee(uint256 amount) external view returns (uint256);\n\n    /// @notice Calculates the combined performance and protocol fee in shares\n    /// @param vault Address of the vault\n    /// @param asset Asset used for pricing\n    /// @param priceD18 Current vault share price for the specific `asset` (price = shares / assets)\n    /// @param totalShares Total shares of the vault\n    /// @return shares Fee to be added in shares\n    function calculateFee(address vault, address asset, uint256 priceD18, uint256 totalShares)\n        external\n        view\n        returns (uint256 shares);\n\n    /// @notice Sets the recipient address for all collected fees\n    /// @param feeRecipient_ Address to receive fees\n    function setFeeRecipient(address feeRecipient_) external;\n\n    /// @notice Sets the global fee configuration (deposit, redeem, performance, protocol)\n    /// @dev Total of all fees must be <= 1e6 (i.e. 100%)\n    function setFees(uint24 depositFeeD6_, uint24 redeemFeeD6_, uint24 performanceFeeD6_, uint24 protocolFeeD6_)\n        external;\n\n    /// @notice Sets the base asset for a vault, required for performance fee calculation\n    /// @dev Can only be set once per vault\n    function setBaseAsset(address vault, address baseAsset_) external;\n\n    /// @notice Updates the vault's state (min price and timestamp) based on asset price only if `asset` == `baseAssets[vault]`\n    /// @dev Used by the vault to notify FeeManager of new price highs or protocol fee accrual checkpoints\n    function updateState(address asset, uint256 priceD18) external;\n\n    /// @notice Emitted when the fee recipient is changed\n    event SetFeeRecipient(address indexed feeRecipient);\n\n    /// @notice Emitted when the fee configuration is updated\n    event SetFees(uint24 depositFeeD6, uint24 redeemFeeD6, uint24 performanceFeeD6, uint24 protocolFeeD6);\n\n    /// @notice Emitted when a vault's base asset is set\n    event SetBaseAsset(address indexed vault, address indexed baseAsset);\n\n    /// @notice Emitted when the vault's min price or timestamp is updated\n    event UpdateState(address indexed vault, address indexed asset, uint256 priceD18);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.2.0) (proxy/transparent/ProxyAdmin.sol)\n\npragma solidity ^0.8.22;\n\nimport {ITransparentUpgradeableProxy} from \"./TransparentUpgradeableProxy.sol\";\nimport {Ownable} from \"../../access/Ownable.sol\";\n\n/**\n * @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an\n * explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.\n */\ncontract ProxyAdmin is Ownable {\n    /**\n     * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgrade(address,address)`\n     * and `upgradeAndCall(address,address,bytes)` are present, and `upgrade` must be used if no function should be called,\n     * while `upgradeAndCall` will invoke the `receive` function if the third argument is the empty byte string.\n     * If the getter returns `\"5.0.0\"`, only `upgradeAndCall(address,address,bytes)` is present, and the third argument must\n     * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function\n     * during an upgrade.\n     */\n    string public constant UPGRADE_INTERFACE_VERSION = \"5.0.0\";\n\n    /**\n     * @dev Sets the initial owner who can perform upgrades.\n     */\n    constructor(address initialOwner) Ownable(initialOwner) {}\n\n    /**\n     * @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation.\n     * See {TransparentUpgradeableProxy-_dispatchUpgradeToAndCall}.\n     *\n     * Requirements:\n     *\n     * - This contract must be the admin of `proxy`.\n     * - If `data` is empty, `msg.value` must be zero.\n     */\n    function upgradeAndCall(\n        ITransparentUpgradeableProxy proxy,\n        address implementation,\n        bytes memory data\n    ) public payable virtual onlyOwner {\n        proxy.upgradeToAndCall{value: msg.value}(implementation, data);\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Address.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.2.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\nimport {Errors} from \"./Errors.sol\";\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev There's no code at `target` (it is not a contract).\n     */\n    error AddressEmptyCode(address target);\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        if (address(this).balance < amount) {\n            revert Errors.InsufficientBalance(address(this).balance, amount);\n        }\n\n        (bool success, bytes memory returndata) = recipient.call{value: amount}(\"\");\n        if (!success) {\n            _revert(returndata);\n        }\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason or custom error, it is bubbled\n     * up by this function (like regular Solidity function calls). However, if\n     * the call reverted with no returned reason, this function reverts with a\n     * {Errors.FailedCall} error.\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        if (address(this).balance < value) {\n            revert Errors.InsufficientBalance(address(this).balance, value);\n        }\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n     * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case\n     * of an unsuccessful call.\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata\n    ) internal view returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            // only check if target is a contract if the call was successful and the return data is empty\n            // otherwise we already know that it was a contract\n            if (returndata.length == 0 && target.code.length == 0) {\n                revert AddressEmptyCode(target);\n            }\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n     * revert reason or with a default {Errors.FailedCall} error.\n     */\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.\n     */\n    function _revert(bytes memory returndata) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            assembly (\"memory-safe\") {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert Errors.FailedCall();\n        }\n    }\n}\n"},{"file_path":"src/interfaces/modules/IVaultModule.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../factories/IFactory.sol\";\nimport \"../managers/IRiskManager.sol\";\nimport \"./IACLModule.sol\";\nimport \"./IShareModule.sol\";\nimport \"./ISubvaultModule.sol\";\nimport \"./IVerifierModule.sol\";\n\n/// @title IVaultModule\n/// @notice Interface for a VaultModule that manages and coordinates asset flows\n/// and sub-vault connections within a modular vault architecture.\ninterface IVaultModule is IACLModule {\n    /// @dev Thrown when trying to reconnect a subvault that is already connected.\n    error AlreadyConnected(address subvault);\n\n    /// @dev Thrown when trying to disconnect a subvault that is not currently connected.\n    error NotConnected(address subvault);\n\n    /// @dev Thrown when the provided address is not a valid factory-deployed entity.\n    error NotEntity(address subvault);\n\n    /// @dev Thrown when a given subvault is not correctly configured.\n    error InvalidSubvault(address subvault);\n\n    /// @notice Storage structure used to track vault state and subvaults.\n    struct VaultModuleStorage {\n        address riskManager;\n        EnumerableSet.AddressSet subvaults;\n    }\n\n    /// @notice Role that allows the creation of new subvaults.\n    function CREATE_SUBVAULT_ROLE() external view returns (bytes32);\n\n    /// @notice Role that allows disconnecting existing subvaults.\n    function DISCONNECT_SUBVAULT_ROLE() external view returns (bytes32);\n\n    /// @notice Role identifier for reconnecting subvaults.\n    /// @dev Grants permission to reattach a subvault to the vault system.\n    /// This includes both re-connecting a previously disconnected subvault\n    /// and connecting a new, properly configured subvault for the first time.\n    /// Used to maintain modularity and support hot-swapping of subvaults.\n    function RECONNECT_SUBVAULT_ROLE() external view returns (bytes32);\n\n    /// @notice Role that allows pulling assets from subvaults.\n    function PULL_LIQUIDITY_ROLE() external view returns (bytes32);\n\n    /// @notice Role that allows pushing assets into subvaults.\n    function PUSH_LIQUIDITY_ROLE() external view returns (bytes32);\n\n    /// @notice Returns the factory used to deploy new subvaults.\n    function subvaultFactory() external view returns (IFactory);\n\n    /// @notice Returns the factory used to deploy verifiers.\n    function verifierFactory() external view returns (IFactory);\n\n    /// @notice Returns the total number of connected subvaults.\n    function subvaults() external view returns (uint256);\n\n    /// @notice Returns the address of the subvault at a specific index.\n    /// @param index Index in the set of subvaults.\n    function subvaultAt(uint256 index) external view returns (address);\n\n    /// @notice Checks whether a given address is currently an active subvault.\n    /// @param subvault Address to check.\n    function hasSubvault(address subvault) external view returns (bool);\n\n    /// @notice Returns the address of the risk manager module.\n    function riskManager() external view returns (IRiskManager);\n\n    /// @notice Creates and connects a new subvault.\n    /// @param version Version of the subvault contract to deploy.\n    /// @param owner Owner of the newly created subvault.\n    /// @param verifier Verifier contract used for permissions within the subvault.\n    /// @return subvault Address of the newly created subvault.\n    function createSubvault(uint256 version, address owner, address verifier) external returns (address subvault);\n\n    /// @notice Disconnects a subvault from the vault.\n    /// @param subvault Address of the subvault to disconnect.\n    function disconnectSubvault(address subvault) external;\n\n    /// @notice Reconnects a subvault to the main vault system.\n    /// @dev Can be used to reattach either:\n    /// - A previously disconnected subvault, or\n    /// - A newly created and properly configured subvault.\n    /// Requires the caller to have the `RECONNECT_SUBVAULT_ROLE`.\n    /// @param subvault The address of the subvault to reconnect.\n    function reconnectSubvault(address subvault) external;\n\n    /// @notice Sends a specified amount of assets from the vault to a connected subvault.\n    /// @param subvault Address of the destination subvault.\n    /// @param asset Address of the asset to transfer.\n    /// @param value Amount of the asset to send.\n    function pushAssets(address subvault, address asset, uint256 value) external;\n\n    /// @notice Pulls a specified amount of assets from a connected subvault into the vault.\n    /// @param subvault Address of the source subvault.\n    /// @param asset Address of the asset to transfer.\n    /// @param value Amount of the asset to receive.\n    function pullAssets(address subvault, address asset, uint256 value) external;\n\n    /// @notice Internally used function that transfers assets from the vault to a connected subvault.\n    /// @dev Must be invoked by the vault itself via hook execution logic.\n    /// @param subvault Address of the destination subvault.\n    /// @param asset Address of the asset being transferred.\n    /// @param value Amount of the asset being transferred.\n    function hookPushAssets(address subvault, address asset, uint256 value) external;\n\n    /// @notice Internally used function that pulls assets from a connected subvault into the vault.\n    /// @dev Must be invoked by the vault itself via hook execution logic.\n    /// @param subvault Address of the source subvault.\n    /// @param asset Address of the asset being pulled.\n    /// @param value Amount of the asset being pulled.\n    function hookPullAssets(address subvault, address asset, uint256 value) external;\n\n    /// @notice Emitted when a new subvault is created.\n    event SubvaultCreated(address indexed subvault, uint256 version, address indexed owner, address indexed verifier);\n\n    /// @notice Emitted when a subvault is disconnected.\n    event SubvaultDisconnected(address indexed subvault);\n\n    /// @notice Emitted when a subvault is reconnected.\n    event SubvaultReconnected(address indexed subvault, address indexed verifier);\n\n    /// @notice Emitted when assets are pulled from a subvault into the vault.\n    event AssetsPulled(address indexed asset, address indexed subvault, uint256 value);\n\n    /// @notice Emitted when assets are pushed from the vault into a subvault.\n    event AssetsPushed(address indexed asset, address indexed subvault, uint256 value);\n}\n"},{"file_path":"src/interfaces/modules/IVerifierModule.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../permissions/IVerifier.sol\";\nimport \"./IBaseModule.sol\";\n\n/// @notice Interface for the VerifierModule, which integrates with an external IVerifier contract\n/// @dev Used in modular systems to delegate permission checks or validation to a shared verifier\ninterface IVerifierModule is IBaseModule {\n    /// @notice Thrown when a zero address is provided\n    error ZeroAddress();\n\n    /// @notice Internal storage structure for VerifierModule\n    struct VerifierModuleStorage {\n        address verifier; // Address of the IVerifier contract used for external call validation\n    }\n\n    /// @notice Returns the current verifier contract used by the module\n    /// @return Address of the IVerifier contract\n    function verifier() external view returns (IVerifier);\n}\n"},{"file_path":"src/interfaces/managers/IShareManager.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol\";\n\nimport \"../factories/IFactoryEntity.sol\";\nimport \"../modules/IACLModule.sol\";\nimport \"../modules/IShareModule.sol\";\n\n/// @title IShareManager\n/// @notice Interface for managing share allocations, permissions, minting, burning, and user restrictions\ninterface IShareManager is IFactoryEntity {\n    /// @notice Unauthorized call\n    error Forbidden();\n\n    /// @notice Attempted to mint more shares than pre-allocated\n    error InsufficientAllocatedShares(uint256 value, uint256 allocated);\n\n    /// @notice Global lockup not yet expired\n    error GlobalLockupNotExpired(uint256 timestamp, uint32 globalLockup);\n\n    /// @notice Blacklisted account tried to interact\n    error Blacklisted(address account);\n\n    /// @notice Transfers are currently paused\n    error TransferPaused();\n\n    /// @notice Minting is currently paused\n    error MintPaused();\n\n    /// @notice Burning is currently paused\n    error BurnPaused();\n\n    /// @notice Mint would exceed share limit\n    error LimitExceeded(uint256 value, uint256 limit);\n\n    /// @notice Account is not whitelisted to deposit\n    error NotWhitelisted(address account);\n\n    /// @notice Transfer between accounts not allowed by whitelist\n    error TransferNotAllowed(address from, address to);\n\n    /// @notice Provided value was zero\n    error ZeroValue();\n\n    /// @notice Storage layout for ShareManager.\n    struct ShareManagerStorage {\n        /// @notice Address of the vault associated with this ShareManager.\n        address vault;\n        /// @notice Bitpacked configuration flags controlling global minting, burning, transfers, whitelists and lockups.\n        uint256 flags;\n        /// @notice Total shares allocated to all accounts (includes pending shares).\n        uint256 allocatedShares;\n        /// @notice Merkle root for verifying account permissions (used for deposits if whitelist flags are active).\n        bytes32 whitelistMerkleRoot;\n        /// @notice Tracks individual account permissions, blacklist status, and lockup.\n        mapping(address account => AccountInfo) accounts;\n    }\n\n    /// @notice Per-account permission and state tracking.\n    struct AccountInfo {\n        /// @notice Whether the account is allowed to deposit when the `hasWhitelist` flag is active.\n        bool canDeposit;\n        /// @notice Whether the account is allowed to transfer (send or receive) shares when the `hasTransferWhitelist` flag is active.\n        bool canTransfer;\n        /// @notice Whether the account is disallowed to send or receive shares.\n        bool isBlacklisted;\n    }\n\n    /// @notice Decoded configuration flags from `ShareManagerStorage.flags`.\n    struct Flags {\n        /// @notice If true, minting is globally paused.\n        bool hasMintPause;\n        /// @notice If true, burning of shares is globally paused.\n        bool hasBurnPause;\n        /// @notice If true, transfers of shares between accounts are globally paused (only for TokenizedShareManager).\n        bool hasTransferPause;\n        /// @notice If true, deposit access is controlled via onchain whitelist (mapping `accounts`).\n        bool hasWhitelist;\n        /// @notice If true, transfer access is controlled via offchain whitelist (`whitelistMerkleRoot`).\n        bool hasTransferWhitelist;\n        /// @notice Global lockup duration (timestamp in seconds) applied to all users in the vault.\n        uint32 globalLockup;\n    }\n\n    /// @return bytes32 Returns role required to set global flags\n    function SET_FLAGS_ROLE() external view returns (bytes32);\n\n    /// @return bytes32 Returns role required to set per-user flags\n    function SET_ACCOUNT_INFO_ROLE() external view returns (bytes32);\n\n    /// @return bytes32 Returns role required to set new merkle root for whitelist validation\n    function SET_WHITELIST_MERKLE_ROOT_ROLE() external view returns (bytes32);\n\n    /// @return address Returns address of the vault using this ShareManager\n    function vault() external view returns (address);\n\n    /// @return uint256 Total allocated shares\n    function allocatedShares() external view returns (uint256);\n\n    /// @return f Returns current flag structure\n    function flags() external view returns (Flags memory f);\n\n    /// @return bytes32 Returns Merkle root used for deposit whitelist verification\n    function whitelistMerkleRoot() external view returns (bytes32);\n\n    /// @return bool Returns true whether depositor is allowed under current Merkle root and flag settings\n    function isDepositorWhitelisted(address account, bytes32[] calldata merkleProof) external view returns (bool);\n\n    /// @return shares Returns total shares (active + claimable) for an account\n    function sharesOf(address account) external view returns (uint256 shares);\n\n    /// @return shares Returns claimable shares for an account\n    function claimableSharesOf(address account) external view returns (uint256 shares);\n\n    /// @return shares Returns active shares for an account\n    function activeSharesOf(address account) external view returns (uint256 shares);\n\n    /// @return shares Returns total active shares across the vault\n    function activeShares() external view returns (uint256 shares);\n\n    /// @return shares Total shares including active and claimable\n    function totalShares() external view returns (uint256 shares);\n\n    /// @return info Returns account-specific configuration and permissions\n    function accounts(address account) external view returns (AccountInfo memory info);\n\n    /// @notice Internal checks for mint/burn/transfer under flags, lockups, blacklists, etc.\n    function updateChecks(address from, address to) external view;\n\n    /// @notice Triggers share claiming from queue to user\n    function claimShares(address account) external;\n\n    /// @notice Sets permissions and flags for a specific account\n    function setAccountInfo(address account, AccountInfo memory info) external;\n\n    /// @notice Sets global flag bitmask controlling mints, burns, lockups, etc.\n    function setFlags(Flags calldata flags) external;\n\n    /// @notice Sets new whitelist merkle root\n    function setWhitelistMerkleRoot(bytes32 whitelistMerkleRoot) external;\n\n    /// @notice Allocates `shares` that can be later minted via `mintAllocatedShares`\n    function allocateShares(uint256 shares) external;\n\n    /// @notice Mints shares from the allocated pool\n    function mintAllocatedShares(address to, uint256 shares) external;\n\n    /// @notice Mints new shares to a user directly\n    function mint(address to, uint256 shares) external;\n\n    /// @notice Burns user's shares\n    function burn(address account, uint256 amount) external;\n\n    /// @notice 'Locks' user's shares by transferring them to the vault balance\n    function lock(address acount, uint256 amount) external;\n\n    /// @notice One-time vault assignment during initialization\n    function setVault(address vault_) external;\n\n    /// @notice Emitted when shares are allocated or removed (positive/negative)\n    event AllocateShares(int256 value);\n\n    /// @notice Emitted when new shares are minted\n    event Mint(address indexed account, uint256 shares);\n\n    /// @notice Emitted when shares are burned\n    event Burn(address indexed account, uint256 shares);\n\n    /// @notice Emitted when shares are locked\n    event Lock(address account, uint256 value);\n\n    /// @notice Emitted when global flag configuration is changed\n    event SetFlags(Flags flags);\n\n    /// @notice Emitted when whitelist merkle root is changed\n    event SetWhitelistMerkleRoot(bytes32 newWhitelistMerkleRoot);\n\n    /// @notice Emitted when a user account is updated\n    event SetAccountInfo(address indexed account, AccountInfo info);\n\n    /// @notice Emitted when vault is set\n    event SetVault(address indexed vault);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/contracts/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reinitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Pointer to storage slot. Allows integrators to override it with a custom storage location.\n     *\n     * NOTE: Consider following the ERC-7201 formula to derive storage locations.\n     */\n    function _initializableStorageSlot() internal pure virtual returns (bytes32) {\n        return INITIALIZABLE_STORAGE;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        bytes32 slot = _initializableStorageSlot();\n        assembly {\n            $.slot := slot\n        }\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Context.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n\n    function _contextSuffixLength() internal view virtual returns (uint256) {\n        return 0;\n    }\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/Arrays.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/Arrays.sol)\n// This file was procedurally generated from scripts/generate/templates/Arrays.js.\n\npragma solidity ^0.8.20;\n\nimport {Comparators} from \"./Comparators.sol\";\nimport {SlotDerivation} from \"./SlotDerivation.sol\";\nimport {StorageSlot} from \"./StorageSlot.sol\";\nimport {Math} from \"./math/Math.sol\";\n\n/**\n * @dev Collection of functions related to array types.\n */\nlibrary Arrays {\n    using SlotDerivation for bytes32;\n    using StorageSlot for bytes32;\n\n    /**\n     * @dev Sort an array of uint256 (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        uint256[] memory array,\n        function(uint256, uint256) pure returns (bool) comp\n    ) internal pure returns (uint256[] memory) {\n        _quickSort(_begin(array), _end(array), comp);\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of uint256 in increasing order.\n     */\n    function sort(uint256[] memory array) internal pure returns (uint256[] memory) {\n        sort(array, Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Sort an array of address (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        address[] memory array,\n        function(address, address) pure returns (bool) comp\n    ) internal pure returns (address[] memory) {\n        sort(_castToUint256Array(array), _castToUint256Comp(comp));\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of address in increasing order.\n     */\n    function sort(address[] memory array) internal pure returns (address[] memory) {\n        sort(_castToUint256Array(array), Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Sort an array of bytes32 (in memory) following the provided comparator function.\n     *\n     * This function does the sorting \"in place\", meaning that it overrides the input. The object is returned for\n     * convenience, but that returned value can be discarded safely if the caller has a memory pointer to the array.\n     *\n     * NOTE: this function's cost is `O(n · log(n))` in average and `O(n²)` in the worst case, with n the length of the\n     * array. Using it in view functions that are executed through `eth_call` is safe, but one should be very careful\n     * when executing this as part of a transaction. If the array being sorted is too large, the sort operation may\n     * consume more gas than is available in a block, leading to potential DoS.\n     *\n     * IMPORTANT: Consider memory side-effects when using custom comparator functions that access memory in an unsafe way.\n     */\n    function sort(\n        bytes32[] memory array,\n        function(bytes32, bytes32) pure returns (bool) comp\n    ) internal pure returns (bytes32[] memory) {\n        sort(_castToUint256Array(array), _castToUint256Comp(comp));\n        return array;\n    }\n\n    /**\n     * @dev Variant of {sort} that sorts an array of bytes32 in increasing order.\n     */\n    function sort(bytes32[] memory array) internal pure returns (bytes32[] memory) {\n        sort(_castToUint256Array(array), Comparators.lt);\n        return array;\n    }\n\n    /**\n     * @dev Performs a quick sort of a segment of memory. The segment sorted starts at `begin` (inclusive), and stops\n     * at end (exclusive). Sorting follows the `comp` comparator.\n     *\n     * Invariant: `begin <= end`. This is the case when initially called by {sort} and is preserved in subcalls.\n     *\n     * IMPORTANT: Memory locations between `begin` and `end` are not validated/zeroed. This function should\n     * be used only if the limits are within a memory array.\n     */\n    function _quickSort(uint256 begin, uint256 end, function(uint256, uint256) pure returns (bool) comp) private pure {\n        unchecked {\n            if (end - begin < 0x40) return;\n\n            // Use first element as pivot\n            uint256 pivot = _mload(begin);\n            // Position where the pivot should be at the end of the loop\n            uint256 pos = begin;\n\n            for (uint256 it = begin + 0x20; it < end; it += 0x20) {\n                if (comp(_mload(it), pivot)) {\n                    // If the value stored at the iterator's position comes before the pivot, we increment the\n                    // position of the pivot and move the value there.\n                    pos += 0x20;\n                    _swap(pos, it);\n                }\n            }\n\n            _swap(begin, pos); // Swap pivot into place\n            _quickSort(begin, pos, comp); // Sort the left side of the pivot\n            _quickSort(pos + 0x20, end, comp); // Sort the right side of the pivot\n        }\n    }\n\n    /**\n     * @dev Pointer to the memory location of the first element of `array`.\n     */\n    function _begin(uint256[] memory array) private pure returns (uint256 ptr) {\n        assembly (\"memory-safe\") {\n            ptr := add(array, 0x20)\n        }\n    }\n\n    /**\n     * @dev Pointer to the memory location of the first memory word (32bytes) after `array`. This is the memory word\n     * that comes just after the last element of the array.\n     */\n    function _end(uint256[] memory array) private pure returns (uint256 ptr) {\n        unchecked {\n            return _begin(array) + array.length * 0x20;\n        }\n    }\n\n    /**\n     * @dev Load memory word (as a uint256) at location `ptr`.\n     */\n    function _mload(uint256 ptr) private pure returns (uint256 value) {\n        assembly {\n            value := mload(ptr)\n        }\n    }\n\n    /**\n     * @dev Swaps the elements memory location `ptr1` and `ptr2`.\n     */\n    function _swap(uint256 ptr1, uint256 ptr2) private pure {\n        assembly {\n            let value1 := mload(ptr1)\n            let value2 := mload(ptr2)\n            mstore(ptr1, value2)\n            mstore(ptr2, value1)\n        }\n    }\n\n    /// @dev Helper: low level cast address memory array to uint256 memory array\n    function _castToUint256Array(address[] memory input) private pure returns (uint256[] memory output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast bytes32 memory array to uint256 memory array\n    function _castToUint256Array(bytes32[] memory input) private pure returns (uint256[] memory output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast address comp function to uint256 comp function\n    function _castToUint256Comp(\n        function(address, address) pure returns (bool) input\n    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /// @dev Helper: low level cast bytes32 comp function to uint256 comp function\n    function _castToUint256Comp(\n        function(bytes32, bytes32) pure returns (bool) input\n    ) private pure returns (function(uint256, uint256) pure returns (bool) output) {\n        assembly {\n            output := input\n        }\n    }\n\n    /**\n     * @dev Searches a sorted `array` and returns the first index that contains\n     * a value greater or equal to `element`. If no such index exists (i.e. all\n     * values in the array are strictly less than `element`), the array length is\n     * returned. Time complexity O(log n).\n     *\n     * NOTE: The `array` is expected to be sorted in ascending order, and to\n     * contain no repeated elements.\n     *\n     * IMPORTANT: Deprecated. This implementation behaves as {lowerBound} but lacks\n     * support for repeated elements in the array. The {lowerBound} function should\n     * be used instead.\n     */\n    function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value > element) {\n                high = mid;\n            } else {\n                low = mid + 1;\n            }\n        }\n\n        // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound.\n        if (low > 0 && unsafeAccess(array, low - 1).value == element) {\n            return low - 1;\n        } else {\n            return low;\n        }\n    }\n\n    /**\n     * @dev Searches an `array` sorted in ascending order and returns the first\n     * index that contains a value greater or equal than `element`. If no such index\n     * exists (i.e. all values in the array are strictly less than `element`), the array\n     * length is returned. Time complexity O(log n).\n     *\n     * See C++'s https://en.cppreference.com/w/cpp/algorithm/lower_bound[lower_bound].\n     */\n    function lowerBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value < element) {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            } else {\n                high = mid;\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Searches an `array` sorted in ascending order and returns the first\n     * index that contains a value strictly greater than `element`. If no such index\n     * exists (i.e. all values in the array are strictly less than `element`), the array\n     * length is returned. Time complexity O(log n).\n     *\n     * See C++'s https://en.cppreference.com/w/cpp/algorithm/upper_bound[upper_bound].\n     */\n    function upperBound(uint256[] storage array, uint256 element) internal view returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeAccess(array, mid).value > element) {\n                high = mid;\n            } else {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Same as {lowerBound}, but with an array in memory.\n     */\n    function lowerBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeMemoryAccess(array, mid) < element) {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            } else {\n                high = mid;\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Same as {upperBound}, but with an array in memory.\n     */\n    function upperBoundMemory(uint256[] memory array, uint256 element) internal pure returns (uint256) {\n        uint256 low = 0;\n        uint256 high = array.length;\n\n        if (high == 0) {\n            return 0;\n        }\n\n        while (low < high) {\n            uint256 mid = Math.average(low, high);\n\n            // Note that mid will always be strictly less than high (i.e. it will be a valid array index)\n            // because Math.average rounds towards zero (it does integer division with truncation).\n            if (unsafeMemoryAccess(array, mid) > element) {\n                high = mid;\n            } else {\n                // this cannot overflow because mid < high\n                unchecked {\n                    low = mid + 1;\n                }\n            }\n        }\n\n        return low;\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(address[] storage arr, uint256 pos) internal pure returns (StorageSlot.AddressSlot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getAddressSlot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(bytes32[] storage arr, uint256 pos) internal pure returns (StorageSlot.Bytes32Slot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getBytes32Slot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeAccess(uint256[] storage arr, uint256 pos) internal pure returns (StorageSlot.Uint256Slot storage) {\n        bytes32 slot;\n        assembly (\"memory-safe\") {\n            slot := arr.slot\n        }\n        return slot.deriveArray().offset(pos).getUint256Slot();\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(address[] memory arr, uint256 pos) internal pure returns (address res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(bytes32[] memory arr, uint256 pos) internal pure returns (bytes32 res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Access an array in an \"unsafe\" way. Skips solidity \"index-out-of-range\" check.\n     *\n     * WARNING: Only use if you are certain `pos` is lower than the array length.\n     */\n    function unsafeMemoryAccess(uint256[] memory arr, uint256 pos) internal pure returns (uint256 res) {\n        assembly {\n            res := mload(add(add(arr, 0x20), mul(pos, 0x20)))\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.\n     */\n    function unsafeSetLength(address[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.\n     */\n    function unsafeSetLength(bytes32[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n\n    /**\n     * @dev Helper to set the length of a dynamic array. Directly writing to `.length` is forbidden.\n     *\n     * WARNING: this does not clear elements if length is reduced, of initialize elements if length is increased.\n     */\n    function unsafeSetLength(uint256[] storage array, uint256 len) internal {\n        assembly (\"memory-safe\") {\n            sstore(array.slot, len)\n        }\n    }\n}\n"},{"file_path":"src/interfaces/queues/IRedeemQueue.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\";\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"@openzeppelin/contracts/utils/structs/Checkpoints.sol\";\nimport \"@openzeppelin/contracts/utils/structs/EnumerableMap.sol\";\n\nimport \"../modules/IVaultModule.sol\";\nimport \"./IQueue.sol\";\n\n/// @title IRedeemQueue\n/// @notice Interface for redeem queues that manage time-delayed redemptions of vault shares into underlying assets.\n/// @dev Handles request creation, price-based batch processing, and asynchronous liquidity settlement.\n///\n/// # Overview\n/// A `RedeemQueue` allows users to request conversion of their vault shares into assets. It introduces a delay enforced by an oracle (`redeemInterval`), and ensures the following invariants:\n/// 1. Each request is defined by `(shares, timestamp)`.\n/// 2. Requests are **not cancellable**, to prevent griefing (e.g., by requesting redemption and cancelling after unstaking starts).\n/// 3. Users may have multiple independent redemption requests.\n///\n/// Once an oracle report is submitted at `reportTimestamp`, it processes all requests with `timestamp <= reportTimestamp - redeemInterval`, converting vault shares into asset values using the reported price.\n///\n/// # Liquidity Processing (Two-Stage)\n/// Redemption handling is decoupled from actual asset movement to allow asynchronous liquidity management:\n/// - After a request is created, vault curators may pull liquidity from external protocols.\n/// - Once oracle report is submitted and enough liquidity is available, vault curator (or any other actor) calls `handleReport()` on the redeem queue.\n/// - This pulls required amount of assets from the Vault (and Subvaults) processing created redemption requests.\n///\n/// # Scalability Approach\n/// Unlike deposits, redemption requests are never cancelled. This allows the system to use a **prefix sum array** to track requests over time.\n///\n/// # Redemption Processing\n/// - When a user redeems `amount` shares at time `T`, the system records `prefixSum[T] += shares`.\n/// - At oracle report time `reportTimestamp`, all requests with `timestamp <= reportTimestamp - redeemInterval` are marked as processed.\n/// - Curator pushes the required assets to the queue by managin vault liquidity and calling `handleBatches` function afterwards.\n/// - Users call `claim(receiver, timestamps[])` to redeem their processed shares for assets.\ninterface IRedeemQueue is IQueue {\n    /// @notice Redemption request metadata for a user.\n    /// @dev Represents a single request to convert vault shares into underlying assets.\n    struct Request {\n        /// @notice Timestamp when the redemption request was submitted.\n        /// @dev Determines eligibility for processing based on oracle report timing and `redeemInterval`.\n        uint256 timestamp;\n        /// @notice Amount of vault shares submitted for redemption.\n        uint256 shares;\n        /// @notice Whether the request has been processed and is now claimable.\n        /// @dev Set to `true` after liquidity has been allocated via `handleBatches`.\n        bool isClaimable;\n        /// @notice Amount of assets that can be claimed by the user.\n        /// @dev Calculated and stored after a matching oracle report has been processed via `handleReport`.\n        uint256 assets;\n    }\n\n    /// @notice Redemption batch result with total matched shares and corresponding assets.\n    /// @dev Represents a single price batch where multiple redemption requests are settled at the same oracle-reported price.\n    struct Batch {\n        /// @notice Total amount of assets allocated for this redemption batch.\n        /// @dev Calculated during `handleReport` using the reported price and total matched shares.\n        uint256 assets;\n        /// @notice Total number of vault shares handled in this batch.\n        /// @dev Includes all user requests processed at the same oracle report.\n        uint256 shares;\n    }\n\n    /// @notice Storage layout for the RedeemQueue contract.\n    /// @dev Tracks redemption request state, oracle-based batch settlements, and pricing checkpoints.\n    struct RedeemQueueStorage {\n        /// @notice Number of timestamp-based redemption checkpoints that have been processed.\n        /// @dev Ensures sequential handling of oracle reports.\n        uint256 handledIndices;\n        /// @notice Number of claimable batches.\n        /// @dev Increments as batches are handled via `handleBatches` and become claimable.\n        uint256 batchIterator;\n        /// @notice Total amount of assets needed to fulfill all currently batched redemption requests.\n        /// @dev Equals the sum of `batches[i].assets` for all indices `i` such that `batchIterator <= i < batches.length`.\n        uint256 totalDemandAssets;\n        /// @notice Total shares from redemption requests that are not yet claimable.\n        /// @dev Increases when users create new redemption requests and decreases after they are processed via `handleBatches`.\n        uint256 totalPendingShares;\n        /// @notice Mapping of redemption requests per user.\n        /// @dev Each user maps to a set of `(timestamp => shares)` representing open requests.\n        mapping(address => EnumerableMap.UintToUintMap) requestsOf;\n        /// @notice Prefix sum of requested shares grouped by timestamp.\n        /// @dev Enables efficient calculation of total demand in a redemption window.\n        mapping(uint256 => uint256) prefixSum;\n        /// @notice Batches created from processed oracle reports.\n        /// @dev Each batch maps total requested shares to the equivalent amount of assets.\n        Batch[] batches;\n        /// @notice Historical oracle pricing checkpoints for batch processing.\n        /// @dev Associates report timestamps with their respective batch index.\n        Checkpoints.Trace224 prices;\n    }\n\n    /// @notice Returns a paginated list of redemption requests for a user.\n    /// @dev Returned requests can be in one of the following states:\n    /// - Pending: Awaiting processing by an oracle report.\n    /// - Handled: Processed by oracle report but not yet claimable (assets not yet pulled from the Vault).\n    /// - Claimable: Processed and fully settled; assets are ready to be claimed.\n    /// @param account Address of the user.\n    /// @param offset Starting index for pagination.\n    /// @param limit Maximum number of requests to return.\n    /// @return requests Array of user's redemption requests with full status metadata.\n    function requestsOf(address account, uint256 offset, uint256 limit)\n        external\n        view\n        returns (Request[] memory requests);\n\n    /// @notice Returns assets and shares for a redemption batch at a given index.\n    /// @param batchIndex Index of the redemption batch.\n    /// @return assets Total assets corresponding to this batch.\n    /// @return shares Total shares redeemed in this batch.\n    function batchAt(uint256 batchIndex) external view returns (uint256 assets, uint256 shares);\n\n    /// @notice Returns the current state of the redeem queue system.\n    /// @return batchIterator Current index of the batch iterator (i.e., next batch to process).\n    /// @return batches Total number of recorded redemption batches.\n    /// @return totalDemandAssets Aggregate amount of redeem requests (in assets) awaiting fulfillment.\n    /// @return totalPendingShares Total number of shares across all redemption requests that are not yet claimable.\n    function getState()\n        external\n        view\n        returns (uint256 batchIterator, uint256 batches, uint256 totalDemandAssets, uint256 totalPendingShares);\n\n    /// @notice Initiates a new redemption by queuing shares for future asset claims.\n    /// @param shares Amount of shares to redeem.\n    function redeem(uint256 shares) external;\n\n    /// @notice Claims redemption requests for a user based on the provided timestamps.\n    /// @dev A request is successfully claimed only if:\n    /// - The associated timestamp has been processed by an oracle report, and\n    /// - The corresponding batch has been settled via `handleBatches`.\n    ///\n    /// The function is idempotent — requests that are already claimed or not yet eligible are skipped without reverting.\n    ///\n    /// @param account Address of the user claiming the redemptions.\n    /// @param timestamps List of request timestamps to claim.\n    /// @return assets Total amount of assets successfully claimed.\n    function claim(address account, uint32[] calldata timestamps) external returns (uint256 assets);\n\n    /// @notice Processes pending redemption batches by pulling required liquidity from the Vault.\n    /// @dev This function fulfills the asset side of redemption requests that have already been priced\n    ///      via oracle reports. For each processed batch:\n    ///      - Assets are pulled from the Vault to the RedeemQueue contract.\n    ///      - Matching shares are marked as claimable for users.\n    ///\n    /// This function enables asynchronous coordination between oracle reporting and vault liquidity management.\n    ///\n    /// @param batches Maximum number of batches to process in this call.\n    /// @return counter Number of successfully processed redemption batches.\n    function handleBatches(uint256 batches) external returns (uint256 counter);\n\n    /// @notice Emitted when a new redemption request is requested.\n    event RedeemRequested(address indexed account, uint256 shares, uint256 timestamp);\n\n    /// @notice Emitted when redemption is claimed by a user.\n    event RedeemRequestClaimed(address indexed account, address indexed receiver, uint256 assets, uint32 timestamp);\n\n    /// @notice Emitted when oracle price reports are processed.\n    event RedeemRequestsHandled(uint256 counter, uint256 demand);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.2.0) (proxy/ERC1967/ERC1967Proxy.sol)\n\npragma solidity ^0.8.22;\n\nimport {Proxy} from \"../Proxy.sol\";\nimport {ERC1967Utils} from \"./ERC1967Utils.sol\";\n\n/**\n * @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an\n * implementation address that can be changed. This address is stored in storage in the location specified by\n * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967], so that it doesn't conflict with the storage layout of the\n * implementation behind the proxy.\n */\ncontract ERC1967Proxy is Proxy {\n    /**\n     * @dev Initializes the upgradeable proxy with an initial implementation specified by `implementation`.\n     *\n     * If `_data` is nonempty, it's used as data in a delegate call to `implementation`. This will typically be an\n     * encoded function call, and allows initializing the storage of the proxy like a Solidity constructor.\n     *\n     * Requirements:\n     *\n     * - If `data` is empty, `msg.value` must be zero.\n     */\n    constructor(address implementation, bytes memory _data) payable {\n        ERC1967Utils.upgradeToAndCall(implementation, _data);\n    }\n\n    /**\n     * @dev Returns the current implementation address.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using\n     * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`\n     */\n    function _implementation() internal view virtual override returns (address) {\n        return ERC1967Utils.getImplementation();\n    }\n}\n"},{"file_path":"src/interfaces/factories/IFactory.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"./IFactoryEntity.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\";\nimport \"@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol\";\nimport \"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\";\n\n/// @title IFactory\n/// @notice Interface for a factory that manages deployable upgradeable proxies and implementation governance.\ninterface IFactory is IFactoryEntity {\n    /// @notice Thrown when attempting to access an index outside the valid range.\n    error OutOfBounds(uint256 index);\n\n    /// @notice Thrown when trying to use an implementation version that is blacklisted.\n    error BlacklistedVersion(uint256 version);\n\n    /// @notice Thrown when an implementation is already in the accepted list.\n    error ImplementationAlreadyAccepted(address implementation);\n\n    /// @notice Thrown when an implementation has already been proposed.\n    error ImplementationAlreadyProposed(address implementation);\n\n    /// @notice Thrown when attempting to accept an implementation that was never proposed.\n    error ImplementationNotProposed(address implementation);\n\n    /// @dev Internal storage structure for tracking factory state.\n    struct FactoryStorage {\n        EnumerableSet.AddressSet entities; // Set of deployed upgradeable proxies\n        EnumerableSet.AddressSet implementations; // Set of accepted implementation addresses\n        EnumerableSet.AddressSet proposals; // Set of currently proposed (but not yet accepted) implementations\n        mapping(uint256 version => bool) isBlacklisted; // Tracks whether a given version is blacklisted\n    }\n\n    /// @notice Returns the total number of deployed entities (proxies).\n    function entities() external view returns (uint256);\n\n    /// @notice Returns the address of the deployed entity at a given index.\n    function entityAt(uint256 index) external view returns (address);\n\n    /// @notice Returns whether the given address is a deployed entity.\n    function isEntity(address entity) external view returns (bool);\n\n    /// @notice Returns the total number of accepted implementation contracts.\n    function implementations() external view returns (uint256);\n\n    /// @notice Returns the implementation address at the given index.\n    function implementationAt(uint256 index) external view returns (address);\n\n    /// @notice Returns the number of currently proposed (pending) implementations.\n    function proposals() external view returns (uint256);\n\n    /// @notice Returns the address of a proposed implementation at a given index.\n    function proposalAt(uint256 index) external view returns (address);\n\n    /// @notice Returns whether the given implementation version is blacklisted.\n    function isBlacklisted(uint256 version) external view returns (bool);\n\n    /// @notice Updates the blacklist status for a specific implementation version.\n    /// @param version The version index to update.\n    /// @param flag True to blacklist, false to unblacklist.\n    function setBlacklistStatus(uint256 version, bool flag) external;\n\n    /// @notice Proposes a new implementation for future deployment.\n    /// @param implementation The address of the proposed implementation contract.\n    function proposeImplementation(address implementation) external;\n\n    /// @notice Approves a previously proposed implementation, allowing it to be used for deployments.\n    /// @param implementation The address of the proposed implementation to approve.\n    function acceptProposedImplementation(address implementation) external;\n\n    /// @notice Deploys a new TransparentUpgradeableProxy using an accepted implementation.\n    /// @param version The version index of the implementation to use.\n    /// @param owner The address that will become the owner of the proxy.\n    /// @param initParams Calldata to be passed for initialization of the new proxy instance.\n    /// @return instance The address of the newly deployed proxy contract.\n    function create(uint256 version, address owner, bytes calldata initParams) external returns (address instance);\n\n    /// @notice Emitted when the blacklist status of a version is updated.\n    event SetBlacklistStatus(uint256 version, bool flag);\n\n    /// @notice Emitted when a new implementation is proposed.\n    event ProposeImplementation(address implementation);\n\n    /// @notice Emitted when a proposed implementation is accepted.\n    event AcceptProposedImplementation(address implementation);\n\n    /// @notice Emitted when a new proxy instance is successfully deployed.\n    event Created(address indexed instance, uint256 indexed version, address indexed owner, bytes initParams);\n}\n"},{"file_path":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (utils/structs/EnumerableMap.sol)\n// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.\n\npragma solidity ^0.8.20;\n\nimport {EnumerableSet} from \"./EnumerableSet.sol\";\n\n/**\n * @dev Library for managing an enumerable variant of Solidity's\n * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]\n * type.\n *\n * Maps have the following properties:\n *\n * - Entries are added, removed, and checked for existence in constant time\n * (O(1)).\n * - Entries are enumerated in O(n). No guarantees are made on the ordering.\n * - Map can be cleared (all entries removed) in O(n).\n *\n * ```solidity\n * contract Example {\n *     // Add the library methods\n *     using EnumerableMap for EnumerableMap.UintToAddressMap;\n *\n *     // Declare a set state variable\n *     EnumerableMap.UintToAddressMap private myMap;\n * }\n * ```\n *\n * The following map types are supported:\n *\n * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0\n * - `address -> uint256` (`AddressToUintMap`) since v4.6.0\n * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0\n * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0\n * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0\n * - `uint256 -> bytes32` (`UintToBytes32Map`) since v5.1.0\n * - `address -> address` (`AddressToAddressMap`) since v5.1.0\n * - `address -> bytes32` (`AddressToBytes32Map`) since v5.1.0\n * - `bytes32 -> address` (`Bytes32ToAddressMap`) since v5.1.0\n *\n * [WARNING]\n * ====\n * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure\n * unusable.\n * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.\n *\n * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an\n * array of EnumerableMap.\n * ====\n */\nlibrary EnumerableMap {\n    using EnumerableSet for EnumerableSet.Bytes32Set;\n\n    // To implement this library for multiple types with as little code repetition as possible, we write it in\n    // terms of a generic Map type with bytes32 keys and values. The Map implementation uses private functions,\n    // and user-facing implementations such as `UintToAddressMap` are just wrappers around the underlying Map.\n    // This means that we can only create new EnumerableMaps for types that fit in bytes32.\n\n    /**\n     * @dev Query for a nonexistent map key.\n     */\n    error EnumerableMapNonexistentKey(bytes32 key);\n\n    struct Bytes32ToBytes32Map {\n        // Storage of keys\n        EnumerableSet.Bytes32Set _keys;\n        mapping(bytes32 key => bytes32) _values;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) {\n        map._values[key] = value;\n        return map._keys.add(key);\n    }\n\n    /**\n     * @dev Removes a key-value pair from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {\n        delete map._values[key];\n        return map._keys.remove(key);\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(Bytes32ToBytes32Map storage map) internal {\n        uint256 len = length(map);\n        for (uint256 i = 0; i < len; ++i) {\n            delete map._values[map._keys.at(i)];\n        }\n        map._keys.clear();\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {\n        return map._keys.contains(key);\n    }\n\n    /**\n     * @dev Returns the number of key-value pairs in the map. O(1).\n     */\n    function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {\n        return map._keys.length();\n    }\n\n    /**\n     * @dev Returns the key-value pair stored at position `index` in the map. O(1).\n     *\n     * Note that there are no guarantees on the ordering of entries inside the\n     * array, and it may change when more entries are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32 key, bytes32 value) {\n        bytes32 atKey = map._keys.at(index);\n        return (atKey, map._values[atKey]);\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool exists, bytes32 value) {\n        bytes32 val = map._values[key];\n        if (val == bytes32(0)) {\n            return (contains(map, key), bytes32(0));\n        } else {\n            return (true, val);\n        }\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {\n        bytes32 value = map._values[key];\n        if (value == 0 && !contains(map, key)) {\n            revert EnumerableMapNonexistentKey(key);\n        }\n        return value;\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) {\n        return map._keys.values();\n    }\n\n    // UintToUintMap\n\n    struct UintToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) {\n        return set(map._inner, bytes32(key), bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(UintToUintMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToUintMap storage map, uint256 index) internal view returns (uint256 key, uint256 value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (uint256(atKey), uint256(val));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool exists, uint256 value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(key));\n        return (success, uint256(val));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(key)));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToUintMap storage map) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintToAddressMap\n\n    struct UintToAddressMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {\n        return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(UintToAddressMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToAddressMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256 key, address value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (uint256(atKey), address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool exists, address value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(key));\n        return (success, address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, bytes32(key)))));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // UintToBytes32Map\n\n    struct UintToBytes32Map {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(UintToBytes32Map storage map, uint256 key, bytes32 value) internal returns (bool) {\n        return set(map._inner, bytes32(key), value);\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(UintToBytes32Map storage map, uint256 key) internal returns (bool) {\n        return remove(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(UintToBytes32Map storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(UintToBytes32Map storage map, uint256 key) internal view returns (bool) {\n        return contains(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(UintToBytes32Map storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(UintToBytes32Map storage map, uint256 index) internal view returns (uint256 key, bytes32 value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (uint256(atKey), val);\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(UintToBytes32Map storage map, uint256 key) internal view returns (bool exists, bytes32 value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(key));\n        return (success, val);\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(UintToBytes32Map storage map, uint256 key) internal view returns (bytes32) {\n        return get(map._inner, bytes32(key));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(UintToBytes32Map storage map) internal view returns (uint256[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        uint256[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressToUintMap\n\n    struct AddressToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) {\n        return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(AddressToUintMap storage map, address key) internal returns (bool) {\n        return remove(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(AddressToUintMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(AddressToUintMap storage map, address key) internal view returns (bool) {\n        return contains(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(AddressToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressToUintMap storage map, uint256 index) internal view returns (address key, uint256 value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (address(uint160(uint256(atKey))), uint256(val));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(AddressToUintMap storage map, address key) internal view returns (bool exists, uint256 value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key))));\n        return (success, uint256(val));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(AddressToUintMap storage map, address key) internal view returns (uint256) {\n        return uint256(get(map._inner, bytes32(uint256(uint160(key)))));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(AddressToUintMap storage map) internal view returns (address[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressToAddressMap\n\n    struct AddressToAddressMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(AddressToAddressMap storage map, address key, address value) internal returns (bool) {\n        return set(map._inner, bytes32(uint256(uint160(key))), bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(AddressToAddressMap storage map, address key) internal returns (bool) {\n        return remove(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(AddressToAddressMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(AddressToAddressMap storage map, address key) internal view returns (bool) {\n        return contains(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(AddressToAddressMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressToAddressMap storage map, uint256 index) internal view returns (address key, address value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (address(uint160(uint256(atKey))), address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(AddressToAddressMap storage map, address key) internal view returns (bool exists, address value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key))));\n        return (success, address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(AddressToAddressMap storage map, address key) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, bytes32(uint256(uint160(key)))))));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(AddressToAddressMap storage map) internal view returns (address[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // AddressToBytes32Map\n\n    struct AddressToBytes32Map {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(AddressToBytes32Map storage map, address key, bytes32 value) internal returns (bool) {\n        return set(map._inner, bytes32(uint256(uint160(key))), value);\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(AddressToBytes32Map storage map, address key) internal returns (bool) {\n        return remove(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(AddressToBytes32Map storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(AddressToBytes32Map storage map, address key) internal view returns (bool) {\n        return contains(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(AddressToBytes32Map storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(AddressToBytes32Map storage map, uint256 index) internal view returns (address key, bytes32 value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (address(uint160(uint256(atKey))), val);\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(AddressToBytes32Map storage map, address key) internal view returns (bool exists, bytes32 value) {\n        (bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key))));\n        return (success, val);\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(AddressToBytes32Map storage map, address key) internal view returns (bytes32) {\n        return get(map._inner, bytes32(uint256(uint160(key))));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(AddressToBytes32Map storage map) internal view returns (address[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        address[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // Bytes32ToUintMap\n\n    struct Bytes32ToUintMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) {\n        return set(map._inner, key, bytes32(value));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {\n        return remove(map._inner, key);\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(Bytes32ToUintMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {\n        return contains(map._inner, key);\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(Bytes32ToUintMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32 key, uint256 value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (atKey, uint256(val));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool exists, uint256 value) {\n        (bool success, bytes32 val) = tryGet(map._inner, key);\n        return (success, uint256(val));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {\n        return uint256(get(map._inner, key));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n\n    // Bytes32ToAddressMap\n\n    struct Bytes32ToAddressMap {\n        Bytes32ToBytes32Map _inner;\n    }\n\n    /**\n     * @dev Adds a key-value pair to a map, or updates the value for an existing\n     * key. O(1).\n     *\n     * Returns true if the key was added to the map, that is if it was not\n     * already present.\n     */\n    function set(Bytes32ToAddressMap storage map, bytes32 key, address value) internal returns (bool) {\n        return set(map._inner, key, bytes32(uint256(uint160(value))));\n    }\n\n    /**\n     * @dev Removes a value from a map. O(1).\n     *\n     * Returns true if the key was removed from the map, that is if it was present.\n     */\n    function remove(Bytes32ToAddressMap storage map, bytes32 key) internal returns (bool) {\n        return remove(map._inner, key);\n    }\n\n    /**\n     * @dev Removes all the entries from a map. O(n).\n     *\n     * WARNING: Developers should keep in mind that this function has an unbounded cost and using it may render the\n     * function uncallable if the map grows to the point where clearing it consumes too much gas to fit in a block.\n     */\n    function clear(Bytes32ToAddressMap storage map) internal {\n        clear(map._inner);\n    }\n\n    /**\n     * @dev Returns true if the key is in the map. O(1).\n     */\n    function contains(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool) {\n        return contains(map._inner, key);\n    }\n\n    /**\n     * @dev Returns the number of elements in the map. O(1).\n     */\n    function length(Bytes32ToAddressMap storage map) internal view returns (uint256) {\n        return length(map._inner);\n    }\n\n    /**\n     * @dev Returns the element stored at position `index` in the map. O(1).\n     * Note that there are no guarantees on the ordering of values inside the\n     * array, and it may change when more values are added or removed.\n     *\n     * Requirements:\n     *\n     * - `index` must be strictly less than {length}.\n     */\n    function at(Bytes32ToAddressMap storage map, uint256 index) internal view returns (bytes32 key, address value) {\n        (bytes32 atKey, bytes32 val) = at(map._inner, index);\n        return (atKey, address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Tries to returns the value associated with `key`. O(1).\n     * Does not revert if `key` is not in the map.\n     */\n    function tryGet(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool exists, address value) {\n        (bool success, bytes32 val) = tryGet(map._inner, key);\n        return (success, address(uint160(uint256(val))));\n    }\n\n    /**\n     * @dev Returns the value associated with `key`. O(1).\n     *\n     * Requirements:\n     *\n     * - `key` must be in the map.\n     */\n    function get(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (address) {\n        return address(uint160(uint256(get(map._inner, key))));\n    }\n\n    /**\n     * @dev Return the an array containing all the keys\n     *\n     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\n     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\n     * this function has an unbounded cost, and using it as part of a state-changing function may render the function\n     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.\n     */\n    function keys(Bytes32ToAddressMap storage map) internal view returns (bytes32[] memory) {\n        bytes32[] memory store = keys(map._inner);\n        bytes32[] memory result;\n\n        assembly (\"memory-safe\") {\n            result := store\n        }\n\n        return result;\n    }\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"uint256","name":"version_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AlreadySupportedAsset","type":"error"},{"inputs":[],"name":"Forbidden","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[{"internalType":"uint256","name":"priceD18","type":"uint256"}],"name":"InvalidPrice","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"minTimestamp","type":"uint256"}],"name":"TooEarly","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"UnsupportedAsset","type":"error"},{"inputs":[],"name":"ZeroValue","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"initParams","type":"bytes"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"uint224","name":"priceD18","type":"uint224"},{"indexed":true,"internalType":"uint32","name":"timestamp","type":"uint32"}],"name":"ReportAccepted","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint224","name":"priceD18","type":"uint224"}],"indexed":false,"internalType":"struct IOracle.Report[]","name":"reports","type":"tuple[]"}],"name":"ReportsSubmitted","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint224","name":"maxAbsoluteDeviation","type":"uint224"},{"internalType":"uint224","name":"suspiciousAbsoluteDeviation","type":"uint224"},{"internalType":"uint64","name":"maxRelativeDeviationD18","type":"uint64"},{"internalType":"uint64","name":"suspiciousRelativeDeviationD18","type":"uint64"},{"internalType":"uint32","name":"timeout","type":"uint32"},{"internalType":"uint32","name":"depositInterval","type":"uint32"},{"internalType":"uint32","name":"redeemInterval","type":"uint32"}],"indexed":false,"internalType":"struct IOracle.SecurityParams","name":"securityParams","type":"tuple"}],"name":"SecurityParamsSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"}],"name":"SetVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"assets","type":"address[]"}],"name":"SupportedAssetsAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"assets","type":"address[]"}],"name":"SupportedAssetsRemoved","type":"event"},{"inputs":[],"name":"ACCEPT_REPORT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ADD_SUPPORTED_ASSETS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REMOVE_SUPPORTED_ASSETS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_SECURITY_PARAMS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUBMIT_REPORTS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"priceD18","type":"uint256"},{"internalType":"uint32","name":"timestamp","type":"uint32"}],"name":"acceptReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"}],"name":"addSupportedAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getReport","outputs":[{"components":[{"internalType":"uint224","name":"priceD18","type":"uint224"},{"internalType":"uint32","name":"timestamp","type":"uint32"},{"internalType":"bool","name":"isSuspicious","type":"bool"}],"internalType":"struct IOracle.DetailedReport","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"initParams","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"isSupportedAsset","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"assets","type":"address[]"}],"name":"removeSupportedAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"securityParams","outputs":[{"components":[{"internalType":"uint224","name":"maxAbsoluteDeviation","type":"uint224"},{"internalType":"uint224","name":"suspiciousAbsoluteDeviation","type":"uint224"},{"internalType":"uint64","name":"maxRelativeDeviationD18","type":"uint64"},{"internalType":"uint64","name":"suspiciousRelativeDeviationD18","type":"uint64"},{"internalType":"uint32","name":"timeout","type":"uint32"},{"internalType":"uint32","name":"depositInterval","type":"uint32"},{"internalType":"uint32","name":"redeemInterval","type":"uint32"}],"internalType":"struct IOracle.SecurityParams","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint224","name":"maxAbsoluteDeviation","type":"uint224"},{"internalType":"uint224","name":"suspiciousAbsoluteDeviation","type":"uint224"},{"internalType":"uint64","name":"maxRelativeDeviationD18","type":"uint64"},{"internalType":"uint64","name":"suspiciousRelativeDeviationD18","type":"uint64"},{"internalType":"uint32","name":"timeout","type":"uint32"},{"internalType":"uint32","name":"depositInterval","type":"uint32"},{"internalType":"uint32","name":"redeemInterval","type":"uint32"}],"internalType":"struct IOracle.SecurityParams","name":"securityParams_","type":"tuple"}],"name":"setSecurityParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault_","type":"address"}],"name":"setVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint224","name":"priceD18","type":"uint224"}],"internalType":"struct IOracle.Report[]","name":"reports","type":"tuple[]"}],"name":"submitReports","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"supportedAssetAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supportedAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"priceD18","type":"uint256"},{"internalType":"address","name":"asset","type":"address"}],"name":"validatePrice","outputs":[{"internalType":"bool","name":"isValid","type":"bool"},{"internalType":"bool","name":"isSuspicious","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract IShareModule","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":"0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000064d656c6c6f770000000000000000000000000000000000000000000000000000"}