{"file_path":"src/vaults/Vault.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../interfaces/factories/IFactoryEntity.sol\";\n\nimport \"../modules/ACLModule.sol\";\nimport \"../modules/ShareModule.sol\";\nimport \"../modules/VaultModule.sol\";\n\ncontract Vault is IFactoryEntity, VaultModule, ShareModule {\n    struct RoleHolder {\n        bytes32 role;\n        address holder;\n    }\n\n    constructor(\n        string memory name_,\n        uint256 version_,\n        address depositQueueFactory_,\n        address redeemQueueFactory_,\n        address subvaultFactory_,\n        address verifierFactory_\n    )\n        ACLModule(name_, version_)\n        ShareModule(name_, version_, depositQueueFactory_, redeemQueueFactory_)\n        VaultModule(name_, version_, subvaultFactory_, verifierFactory_)\n    {}\n\n    function initialize(bytes calldata initParams) external initializer {\n        {\n            (\n                address admin_,\n                address shareManager_,\n                address feeManager_,\n                address riskManager_,\n                address oracle_,\n                address defaultDepositHook_,\n                address defaultRedeemHook_,\n                uint256 queueLimit_,\n                RoleHolder[] memory roleHolders\n            ) = abi.decode(\n                initParams, (address, address, address, address, address, address, address, uint256, RoleHolder[])\n            );\n            __BaseModule_init();\n            __ACLModule_init(admin_);\n            __ShareModule_init(\n                shareManager_, feeManager_, oracle_, defaultDepositHook_, defaultRedeemHook_, queueLimit_\n            );\n            __VaultModule_init(riskManager_);\n            for (uint256 i = 0; i < roleHolders.length; i++) {\n                _grantRole(roleHolders[i].role, roleHolders[i].holder);\n            }\n        }\n        emit Initialized(initParams);\n    }\n}\n","deployed_bytecode":"0x6080604052600436106103ed575f3560e01c8063850260ff1161020a578063b014f4451161011e578063e4f8d0e6116100a8578063eb56d52d11610078578063eb56d52d14610cc3578063ec0f580014610ce2578063ecef475f14610d01578063f31cb0c614610d20578063f68e730414610d3f575f80fd5b8063e4f8d0e614610c33578063e6c8cd9f14610c52578063e6ed8d7414610c71578063e984f35314610ca4575f80fd5b8063ca15c873116100ee578063ca15c87314610b8f578063d0fb020314610bae578063d27d250314610bc2578063d547741f14610be1578063d8b07a6514610c00575f80fd5b8063b014f44514610aff578063b1a62e3b14610b1e578063b2b71a2714610b51578063b91c935c14610b70575f80fd5b80639ff2cb9d1161019f578063a3246ad31161016f578063a3246ad314610a4e578063a35f620a14610a7a578063a567fb4714610a8e578063aa9239f514610aad578063adf167ce14610acc575f80fd5b80639ff2cb9d146109d5578063a0aead4d14610a08578063a217fddf14610a1c578063a2cb31e514610a2f575f80fd5b806392e6ece5116101da57806392e6ece5146109455780639662d42914610964578063974d942e146109975780639bd0911b146109b6575f80fd5b8063850260ff146108c95780638679ed7c146108e85780639010d07c1461090757806391d1485414610926575f80fd5b8063419a2053116103015780635636d54911610296578063651ae6c711610266578063651ae6c71461081c578063663ade061461084f5780636b8b1ccd146108825780637dc0d1d0146108965780638333903b146108aa575f80fd5b80635636d549146107ad57806358b7bf30146107c15780635c60173d146107f45780635d66b00a14610808575f80fd5b80634b694b96116102d15780634b694b961461071d5780634b812c1f1461073c57806352278ab71461075b57806352fd42541461077a575f80fd5b8063419a2053146106b7578063439fab91146106cb57806347842663146106ea5780634a46b4cf146106fe575f80fd5b80632f2ff15d1161038257806336568abe1161035257806336568abe146105fb578063370488161461061a578063387db78f146106395780633d4304e6146106845780634015b2a8146106a3575f80fd5b80632f2ff15d146105765780632f8ecb50146105955780633314bbb9146105b45780633471b337146105e7575f80fd5b806317cbc8b1116103bd57806317cbc8b1146104d25780631c14724f146104f15780631ca0027a14610510578063248a9ca314610557575f80fd5b806301ffc9a7146103f8578063040bee6d1461042c57806313cb953a1461044d578063150b7a021461048e575f80fd5b366103f457005b5f80fd5b348015610403575f80fd5b50610417610412366004613b76565b610d5f565b60405190151581526020015b60405180910390f35b348015610437575f80fd5b5061044b610446366004613bb1565b610d89565b005b348015610458575f80fd5b506104807f32a781031f04cc60b32394e40124d1e87f54273bf26d0532a115a424f6a9329881565b604051908152602001610423565b348015610499575f80fd5b506104b96104a8366004613c11565b630a85bd0160e11b95945050505050565b6040516001600160e01b03199091168152602001610423565b3480156104dd575f80fd5b5061044b6104ec366004613c7f565b610fa9565b3480156104fc575f80fd5b5061048061050b366004613bb1565b611002565b34801561051b575f80fd5b5061054861052a366004613cbd565b60408051602080820183525f90915281519081019091529054815290565b60405190518152602001610423565b348015610562575f80fd5b50610480610571366004613cbd565b61112b565b348015610581575f80fd5b5061044b610590366004613cd4565b61114b565b3480156105a0575f80fd5b5061044b6105af366004613bb1565b611167565b3480156105bf575f80fd5b506104807f68895691ff006f290ca74825ce06ed17fffab55af49f0274f49b7424f752583a81565b3480156105f2575f80fd5b50610480611224565b348015610606575f80fd5b5061044b610615366004613cd4565b611236565b348015610625575f80fd5b5061044b610634366004613bb1565b61126e565b348015610644575f80fd5b5061066c7f00000000000000000000000004b30b1e98950e6a13550d84e991be0d734c2c6181565b6040516001600160a01b039091168152602001610423565b34801561068f575f80fd5b5061066c61069e366004613bb1565b6112e8565b3480156106ae575f80fd5b5061066c611367565b3480156106c2575f80fd5b50610480611382565b3480156106d6575f80fd5b5061044b6106e5366004613d02565b6113b1565b3480156106f5575f80fd5b5061066c61158e565b348015610709575f80fd5b50610417610718366004613cbd565b6115c0565b348015610728575f80fd5b50610417610737366004613bb1565b6115eb565b348015610747575f80fd5b5061066c610756366004613d41565b61167a565b348015610766575f80fd5b50610480610775366004613bb1565b611959565b348015610785575f80fd5b5061066c7f000000000000000000000000bb92a7b9695750e1234bab18f83b73686dd0985481565b3480156107b8575f80fd5b5061066c611985565b3480156107cc575f80fd5b506104807fb557d53a2e72d8333ffa3bf2f556678becb5e995b0e25b7dca354627e550c08f81565b3480156107ff575f80fd5b5061066c6119a0565b348015610813575f80fd5b506104806119a9565b348015610827575f80fd5b506104807f9a4c49d6fb9452bbfe187968075d0fac7d7202d2b7f731d8cffbce9cf66756b281565b34801561085a575f80fd5b506104807ff610639f4b9b8986f875fcb4e49486da5c7aa449a6942b5013fabd061e9b9fff81565b34801561088d575f80fd5b50610480611b18565b3480156108a1575f80fd5b5061066c611b2a565b3480156108b5575f80fd5b506104176108c4366004613bb1565b611b45565b3480156108d4575f80fd5b5061044b6108e3366004613d8d565b611b73565b3480156108f3575f80fd5b50610417610902366004613bb1565b611e20565b348015610912575f80fd5b5061066c610921366004613e0d565b611e4d565b348015610931575f80fd5b50610417610940366004613cd4565b611e72565b348015610950575f80fd5b5061041761095f366004613bb1565b611ea8565b34801561096f575f80fd5b5061066c7f000000000000000000000000fe76b5fd238553d65ce6dd0a572c0fda629f842181565b3480156109a2575f80fd5b5061044b6109b1366004613e45565b611ed5565b3480156109c1575f80fd5b5061066c6109d0366004613cbd565b6123a4565b3480156109e0575f80fd5b5061066c7f00000000000000000000000075fe0d73d3c64cdc1c6449d9f977be6857c4d01181565b348015610a13575f80fd5b506104806123d2565b348015610a27575f80fd5b506104805f81565b348015610a3a575f80fd5b50610480610a49366004613cbd565b6123e6565b348015610a59575f80fd5b50610a6d610a68366004613cbd565b612411565b6040516104239190613ea5565b348015610a85575f80fd5b50610480612441565b348015610a99575f80fd5b50610417610aa8366004613bb1565b61246e565b348015610ab8575f80fd5b5061066c610ac7366004613cbd565b612484565b348015610ad7575f80fd5b506104807f85c2023fdfb1e93dedf5d18f9bc0e79347e071d12740ba71aeb84a4fcbdc4b7981565b348015610b0a575f80fd5b5061044b610b19366004613c7f565b61249a565b348015610b29575f80fd5b506104807f6788636e7899d6d227901dc9f8c4c785401c0991724cf908dc65388af686da6f81565b348015610b5c575f80fd5b5061044b610b6b366004613bb1565b6124c5565b348015610b7b575f80fd5b5061066c610b8a366004613ef1565b612884565b348015610b9a575f80fd5b50610480610ba9366004613cbd565b6128b2565b348015610bb9575f80fd5b5061066c6128d6565b348015610bcd575f80fd5b5061044b610bdc366004613cbd565b6128f1565b348015610bec575f80fd5b5061044b610bfb366004613cd4565b612a98565b348015610c0b575f80fd5b506104807f6618a6d92147bbcacfb2ef2375976fc4c529eeeaeb72a66048296571370c694681565b348015610c3e575f80fd5b5061044b610c4d366004613f1b565b612ab4565b348015610c5d575f80fd5b5061044b610c6c366004613c7f565b612b5d565b348015610c7c575f80fd5b506104807f407fc42eadf1aba68b1d4a8c3c4aa2e8b6beac7957623f3694d0ad77bfb70e0681565b348015610caf575f80fd5b5061044b610cbe366004613c7f565b612b88565b348015610cce575f80fd5b5061044b610cdd366004613f47565b612bc5565b348015610ced575f80fd5b5061044b610cfc366004613bb1565b612c79565b348015610d0c575f80fd5b5061044b610d1b366004613cbd565b612cea565b348015610d2b575f80fd5b5061044b610d3a366004613bb1565b612d58565b348015610d4a575f80fd5b506104805f8051602061433f83398151915281565b5f6001600160e01b03198216635a05180f60e01b1480610d835750610d8382612ea7565b92915050565b7f9a4c49d6fb9452bbfe187968075d0fac7d7202d2b7f731d8cffbce9cf66756b2610db381612edb565b816001600160a01b031663c2f218966040518163ffffffff1660e01b8152600401602060405180830381865afa158015610def573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e139190613f73565b610e3057604051631dd2188d60e31b815260040160405180910390fd5b5f826001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e6d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e919190613f8e565b90505f610e9c612ee8565b6001600160a01b0383165f908152600a820160205260409020909150610ec29085612f0c565b610edf57604051631dd2188d60e31b815260040160405180910390fd5b6001600160a01b038085165f9081526008830160209081526040808320805460ff191690559285168252600a8401905220610f1990612f20565b5f03610f2e57610f2c600b820183612f0c565b505b6001600160a01b0384165f908152600782016020526040812080546001600160a01b0319169055600582018054909190610f6790613fbd565b909155506040516001600160a01b0380841691908616907faf660c1b265f07536d70b577e6dac1fed859eae81dca40591155a8fa2294553d905f90a350505050565b7f68895691ff006f290ca74825ce06ed17fffab55af49f0274f49b7424f752583a610fd381612edb565b610fdb612f29565b610fe6848484612f60565b610ffc60015f8051602061439f83398151915255565b50505050565b5f8061100c612ee8565b9050600b81015f61101c82612f20565b90505f5b81811015611122575f61103384836130a5565b6001600160a01b0381165f908152600a87016020526040812091925061105882612f20565b90505f5b81811015611112575f61106f84836130a5565b6001600160a01b0381165f90815260088b01602052604090205490915060ff161561110957604051638903ab9d60e01b81526001600160a01b038c81166004830152821690638903ab9d90602401602060405180830381865afa1580156110d8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110fc9190613fd2565b611106908b613fe9565b99505b5060010161105c565b5050600190920191506110209050565b50505050919050565b5f9081525f8051602061437f833981519152602052604090206001015490565b6111548261112b565b61115d81612edb565b610ffc83836130b0565b7ff610639f4b9b8986f875fcb4e49486da5c7aa449a6942b5013fabd061e9b9fff61119181612edb565b7fa0dfab7837230c89b90a550f1ff19f8fa745cc29985f05675859eedfef5b80006111bf6001820184612f0c565b6111ec57604051635c6a489f60e01b81526001600160a01b03841660048201526024015b60405180910390fd5b6040516001600160a01b038416907f95067a3324c952e40449419ed59015549ae2c2b2c5988efb9bdaaf33baf6f793905f90a2505050565b5f61122d612ee8565b60050154905090565b6001600160a01b038116331461125f5760405163334bd91960e11b815260040160405180910390fd5b611269828261312a565b505050565b5f8051602061433f83398151915261128581612edb565b8161128e612ee8565b60030180546001600160a01b0319166001600160a01b0392831617905560405160018152908316907f59dc533a8345ccff036afdd89363a87154a5e6c51ff4fc507fc1865bb925438e906020015b60405180910390a25050565b5f806112f2612ee8565b6001600160a01b038085165f908152600783016020526040902054919250168061135d576001600160a01b0384165f90815260088301602052604090205460ff1661134a5760048201546001600160a01b031661135f565b60038201546001600160a01b031661135f565b805b949350505050565b5f611370612ee8565b600401546001600160a01b0316919050565b5f6113ac7f062030953ce644a2a7115259790ad01d3c2b5e8c98fc6b190da443a3f0a7c900612f20565b905090565b5f6113ba6131a6565b805490915060ff600160401b820416159067ffffffffffffffff165f811580156113e15750825b90505f8267ffffffffffffffff1660011480156113fd5750303b155b90508115801561140b575080155b156114295760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561145357845460ff60401b1916600160401b1785555b5f805f805f805f805f8f8f81019061146b919061406a565b9850985098509850985098509850985098506114856131ce565b61148e896131e0565b61149c88888787878761321d565b6114a5866132e6565b5f5b81518110156114fc576114f38282815181106114c5576114c5614217565b60200260200101515f01518383815181106114e2576114e2614217565b6020026020010151602001516130b0565b506001016114a7565b505050505050505050507f5e399709a9ff1709f6f6be7268c8e5c3eeaa9da9cd9797e78f07ef287c3717fe8787604051611537929190614253565b60405180910390a1831561158557845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f7fa0dfab7837230c89b90a550f1ff19f8fa745cc29985f05675859eedfef5b80005b546001600160a01b0316919050565b5f610d837f062030953ce644a2a7115259790ad01d3c2b5e8c98fc6b190da443a3f0a7c90083613356565b5f610d83826115f8612ee8565b600a015f856001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611638573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061165c9190613f8e565b6001600160a01b0316815260208101919091526040015f209061336d565b5f7f85c2023fdfb1e93dedf5d18f9bc0e79347e071d12740ba71aeb84a4fcbdc4b796116a581612edb565b6116ad612f29565b6040516302910f8b60e31b81526001600160a01b0384811660048301527f00000000000000000000000004b30b1e98950e6a13550d84e991be0d734c2c6116906314887c5890602401602060405180830381865afa158015611711573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117359190613f73565b61175d5760405163d0b5c30560e01b81526001600160a01b03841660048201526024016111e3565b306001600160a01b0316836001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117a3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117c79190613f8e565b6001600160a01b0316146117ee57604051631dd2188d60e31b815260040160405180910390fd5b7f00000000000000000000000075fe0d73d3c64cdc1c6449d9f977be6857c4d0116001600160a01b03166346fbcbb2868686306040516020016118479291906001600160a01b0392831681529116602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161187493929190614266565b6020604051808303815f875af1158015611890573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118b49190613f8e565b91506118e360017fa0dfab7837230c89b90a550f1ff19f8fa745cc29985f05675859eedfef5b8000018361338e565b50826001600160a01b0316846001600160a01b0316836001600160a01b03167fae0bbc337ca4971dd982cb61e17432f83cf2e5647ad778f7db9ff18efd77a2118860405161193391815260200190565b60405180910390a461195160015f8051602061439f83398151915255565b509392505050565b5f610d83611965612ee8565b6001600160a01b0384165f908152600a9190910160205260409020612f20565b5f61198e612ee8565b600301546001600160a01b0316919050565b5f6115b1612ee8565b5f803390505f816001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119eb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a0f9190613f8e565b90505f611a1a612ee8565b6001600160a01b0383165f908152600a820160205260409020909150611a40908461336d565b1580611a6557506001600160a01b0383165f90815260088201602052604090205460ff165b15611a8357604051631dd2188d60e31b815260040160405180910390fd5b5f611a8d846112e8565b90506001600160a01b038116611ab057611aa783306133a2565b94505050505090565b604051630af5049b60e11b81526001600160a01b0384811660048301528216906315ea093690602401602060405180830381865afa158015611af4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611aa79190613fd2565b5f611b21612ee8565b60060154905090565b5f611b33612ee8565b600201546001600160a01b0316919050565b5f610d8360017fa0dfab7837230c89b90a550f1ff19f8fa745cc29985f05675859eedfef5b8000018361336d565b611b7b612f29565b7f6788636e7899d6d227901dc9f8c4c785401c0991724cf908dc65388af686da6f611ba581612edb565b5f611bae612ee8565b6002810154604051634df48c7360e11b81526001600160a01b038881166004830152929350911690639be918e690602401602060405180830381865afa158015611bfa573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c1e9190613f73565b611c465760405163ee84f40b60e01b81526001600160a01b03861660048201526024016111e3565b5f81600501546001611c589190613fe9565b90508160060154811115611c7f5760405163082d389160e31b815260040160405180910390fd5b5f88611cab577f000000000000000000000000fe76b5fd238553d65ce6dd0a572c0fda629f8421611ccd565b7f000000000000000000000000bb92a7b9695750e1234bab18f83b73686dd098545b6001600160a01b03166346fbcbb28b8a8a308b8b604051602001611cf494939291906142b1565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401611d2193929190614266565b6020604051808303815f875af1158015611d3d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d619190613f8e565b600584018390556001600160a01b0388165f908152600a850160205260409020909150611d8e908261338e565b50611d9c600b84018861338e565b506001600160a01b038181165f818152600886016020908152604091829020805460ff19168e15159081179091559151918252928a16927f8138cea23ce1869026f924550085f1d5666d82c6c948c921cf9003cac6bfea9c910160405180910390a350505050611e1860015f8051602061439f83398151915255565b505050505050565b5f611e29612ee8565b6001600160a01b039092165f90815260099290920160205250604090205460ff1690565b5f8281525f8051602061435f83398151915260208190526040822061135f90846130a5565b5f9182525f8051602061437f833981519152602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f611eb1612ee8565b6001600160a01b039092165f90815260089290920160205250604090205460ff1690565b611edd612f29565b5f611ee6612ee8565b60028101549091506001600160a01b0316336001600160a01b031614611f1f57604051631dd2188d60e31b815260040160405180910390fd5b80546001820154604051630cd9f5f560e11b81523060048201526001600160a01b0392831692909116905f9082906319b3ebea90602401602060405180830381865afa158015611f71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f959190613f8e565b6001600160a01b0316886001600160a01b031603612242575f826001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fea573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061200e9190613f8e565b604051639d66201b60e01b81526001600160a01b0380831660048301529192508185169163e0e193a29130918d918d918a1690639d66201b90602401602060405180830381865afa158015612065573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120899190613fd2565b896001600160a01b0316633a98ef396040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120c5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120e99190613fd2565b6120f391906142e7565b6040516001600160e01b031960e087901b1681526001600160a01b0394851660048201529390921660248401526001600160e01b031660448301526064820152608401602060405180830381865afa158015612151573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121759190613fd2565b915081156121db576040516340c10f1960e01b81526001600160a01b038281166004830152602482018490528516906340c10f19906044015f604051808303815f87803b1580156121c4575f80fd5b505af11580156121d6573d5f803e3d5ffd5b505050505b604051634d71303160e11b81526001600160a01b038a811660048301526001600160e01b038a166024830152841690639ae26062906044015f604051808303815f87803b15801561222a575f80fd5b505af115801561223c573d5f803e3d5ffd5b50505050505b5f61224b612ee8565b6001600160a01b038a165f908152600a9190910160205260408120915061227182612f20565b90505f5b81811015612329575f61228884836130a5565b6001600160a01b0381165f81815260088b0160205260409020549192509063b8c5ea8a908d9060ff166122bb578b6122bd565b8c5b6040516001600160e01b031960e085901b1681526001600160e01b03909216600483015263ffffffff1660248201526044015f604051808303815f87803b158015612306575f80fd5b505af1158015612318573d5f803e3d5ffd5b505060019093019250612275915050565b506040805163ffffffff808b168252891660208201529081018490526001600160e01b038a16906001600160a01b038c16907f24bbf515a701fcb7a993b1e8c3f201ab4e608f7b85c61b1f8cc0e19dc9d526539060600160405180910390a3505050505050610ffc60015f8051602061439f83398151915255565b5f610d8360017fa0dfab7837230c89b90a550f1ff19f8fa745cc29985f05675859eedfef5b800001836130a5565b5f6113ac6123de612ee8565b600b01612f20565b5f610d837f062030953ce644a2a7115259790ad01d3c2b5e8c98fc6b190da443a3f0a7c900836130a5565b5f8181525f8051602061435f833981519152602081905260409091206060919061243a90613448565b9392505050565b5f6113ac7fa0dfab7837230c89b90a550f1ff19f8fa745cc29985f05675859eedfef5b8000600101612f20565b5f610d838261247b612ee8565b600b019061336d565b5f610d8382612491612ee8565b600b01906130a5565b3330146124ba57604051631dd2188d60e31b815260040160405180910390fd5b611269838383612f60565b7fb557d53a2e72d8333ffa3bf2f556678becb5e995b0e25b7dca354627e550c08f6124ef81612edb565b5f7fa0dfab7837230c89b90a550f1ff19f8fa745cc29985f05675859eedfef5b80006040516302910f8b60e31b81526001600160a01b0385811660048301529192507f00000000000000000000000075fe0d73d3c64cdc1c6449d9f977be6857c4d011909116906314887c5890602401602060405180830381865afa15801561257a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061259e9190613f73565b6125c65760405163d0b5c30560e01b81526001600160a01b03841660048201526024016111e3565b306001600160a01b0316836001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561260c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126309190613f8e565b6001600160a01b0316146126625760405163d034fb7960e01b81526001600160a01b03841660048201526024016111e3565b5f836001600160a01b0316632b7ac3f36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561269f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126c39190613f8e565b6040516302910f8b60e31b81526001600160a01b0380831660048301529192507f00000000000000000000000004b30b1e98950e6a13550d84e991be0d734c2c61909116906314887c5890602401602060405180830381865afa15801561272c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127509190613f73565b6127785760405163d0b5c30560e01b81526001600160a01b03821660048201526024016111e3565b306001600160a01b0316816001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127e29190613f8e565b6001600160a01b03161461280957604051631dd2188d60e31b815260040160405180910390fd5b612816600183018561338e565b61283e57604051638cd80ed360e01b81526001600160a01b03851660048201526024016111e3565b806001600160a01b0316846001600160a01b03167ff75f2e4922769fc299f8f612c31f2d1f8ea0e6fa4c82fdb143bf9c8a070c974c60405160405180910390a350505050565b5f61243a82612891612ee8565b6001600160a01b0386165f908152600a9190910160205260409020906130a5565b5f8181525f8051602061435f83398151915260208190526040822061243a90612f20565b5f6128df612ee8565b600101546001600160a01b0316919050565b5f3390505f816001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612932573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129569190613f8e565b90505f612961612ee8565b90506129908361296f612ee8565b6001600160a01b0385165f908152600a91909101602052604090209061336d565b6129ad57604051631dd2188d60e31b815260040160405180910390fd5b5f6129b7846112e8565b90506001600160a01b03811615612a1b576040516001600160a01b038416602482015260448101869052612a1990829060640160408051601f198184030181529190526020810180516001600160e01b03166330f736c160e21b179052613454565b505b6001600160a01b0384165f90815260088301602052604090205460ff16612a4757612a478385876134c6565b604080518681526001600160a01b03838116602083015280861692908716917fc23ec549723039bc8a35cac0162f81095410795793f7730887eb1a0e06ef5476910160405180910390a35050505050565b612aa18261112b565b612aaa81612edb565b610ffc838361312a565b5f8051602061433f833981519152612acb81612edb565b6001600160a01b038316612af25760405163d92e233d60e01b815260040160405180910390fd5b81612afb612ee8565b6001600160a01b038581165f818152600793909301602052604080842080546001600160a01b03191695841695909517909455925190851692917f329d0838d5265a7d9d220b95803da511a475abe411dc4df364c1d1b8b923cdf991a3505050565b333014612b7d57604051631dd2188d60e31b815260040160405180910390fd5b611269838383613509565b7f32a781031f04cc60b32394e40124d1e87f54273bf26d0532a115a424f6a93298612bb281612edb565b612bba612f29565b610fe6848484613509565b7f6618a6d92147bbcacfb2ef2375976fc4c529eeeaeb72a66048296571370c6946612bef81612edb565b612bf8836115eb565b612c1557604051631dd2188d60e31b815260040160405180910390fd5b81612c1e612ee8565b6001600160a01b0385165f8181526009929092016020526040808320805460ff191694151594909417909355915184151592917f0adde9ce751962c98f81b39c8c220e3e355e0427d8f497ad6533849e0887543d91a3505050565b5f8051602061433f833981519152612c9081612edb565b81612c99612ee8565b60040180546001600160a01b0319166001600160a01b039283161790556040515f8152908316907f59dc533a8345ccff036afdd89363a87154a5e6c51ff4fc507fc1865bb925438e906020016112dc565b7f407fc42eadf1aba68b1d4a8c3c4aa2e8b6beac7957623f3694d0ad77bfb70e06612d1481612edb565b81612d1d612ee8565b600601556040518281527f7abc95a9228ca8caf8cbd0d9add729de5d2032bb1792bb6c5faff0f175f1bd509060200160405180910390a15050565b5f612d61612ee8565b9050600b81015f612d7182612f20565b90505f5b81811015612e6d575f612d8884836130a5565b6001600160a01b0381165f908152600a870160205260408120919250612dad82612f20565b90505f5b81811015612e5d575f612dc484836130a5565b6001600160a01b0381165f90815260088b01602052604090205490915060ff1615612e5457604051630f41a04d60e11b81526001600160a01b038b81166004830152821690631e83409a906024016020604051808303815f875af1158015612e2e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e529190613f73565b505b50600101612db1565b505060019092019150612d759050565b506040516001600160a01b038516907f3a97aa17a51b3fa88e27cdce48823bea308838ed5ea8015ae0598abb1288954b905f90a250505050565b5f6001600160e01b03198216637965db0b60e01b1480610d8357506301ffc9a760e01b6001600160e01b0319831614610d83565b612ee581336135c8565b50565b7f5e907b18dc7e0ef0ce1a83718e9f42938fe96f2ef0fee10bf8326c664faa870090565b5f61243a836001600160a01b038416613601565b5f610d83825490565b5f8051602061439f833981519152805460011901612f5a57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b612f6861158e565b6001600160a01b031663fea34d988484612f81856142fa565b6040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015260448201526064015f604051808303815f87803b158015612fcd575f80fd5b505af1158015612fdf573d5f803e3d5ffd5b50506040516387cd303d60e01b81526001600160a01b03858116600483015260248201859052861692506387cd303d91506044015f604051808303815f87803b15801561302a575f80fd5b505af115801561303c573d5f803e3d5ffd5b50505050826001600160a01b0316826001600160a01b03167f409f90100010c596e4859c24945544ea3430a899b81522dadfd9671b9bc1a4028360405161308591815260200190565b60405180910390a3505050565b60015f8051602061439f83398151915255565b5f61243a83836136e4565b5f6130bb838361370a565b15613122576130ea7f062030953ce644a2a7115259790ad01d3c2b5e8c98fc6b190da443a3f0a7c9008461374c565b1561311a5760405183907fea0f1c470fa813c725756c036120b6688028969f5afbc607918fcd1ff9229435905f90a25b506001610d83565b505f92915050565b5f6131358383613757565b1561312257613143836128b2565b5f0361311a576131737f062030953ce644a2a7115259790ad01d3c2b5e8c98fc6b190da443a3f0a7c90084613790565b5060405183907f4c9a714f78b79aa08074addab7cbdb196cccdf6d67efbf0b99914db8a6b08e73905f90a2506001610d83565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610d83565b6131d661379b565b6131de6137c0565b565b6131e861379b565b6001600160a01b03811661320f5760405163d92e233d60e01b815260040160405180910390fd5b6132195f826130b0565b5050565b61322561379b565b6001600160a01b038616158061324257506001600160a01b038516155b8061325457506001600160a01b038416155b156132725760405163d92e233d60e01b815260040160405180910390fd5b5f61327b612ee8565b80546001600160a01b03199081166001600160a01b03998a161782556001820180548216988a16989098179097556002810180548816968916969096179095555060038401805486169387169390931790925560048301805490941694169390931790915560060155565b6132ee61379b565b6001600160a01b0381166133155760405163d92e233d60e01b815260040160405180910390fd5b7fa0dfab7837230c89b90a550f1ff19f8fa745cc29985f05675859eedfef5b800080546001600160a01b0319166001600160a01b0392909216919091179055565b5f818152600183016020526040812054151561243a565b6001600160a01b0381165f908152600183016020526040812054151561243a565b5f61243a836001600160a01b0384166137d0565b5f73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038416016133d957506001600160a01b03811631610d83565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa15801561341d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134419190613fd2565b9050610d83565b60605f61243a8361381c565b60605f80846001600160a01b0316846040516134709190614314565b5f60405180830381855af49150503d805f81146134a8576040519150601f19603f3d011682016040523d82523d5f602084013e6134ad565b606091505b50915091506134bd858383613875565b95945050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038416016134f55761126982826138d1565b6112696001600160a01b038416838361395d565b61351161158e565b604051631fd469b360e31b81526001600160a01b038581166004830152848116602483015260448201849052919091169063fea34d98906064015f604051808303815f87803b158015613562575f80fd5b505af1158015613574573d5f803e3d5ffd5b505050506135838284836134c6565b826001600160a01b0316826001600160a01b03167f7ceb394e9ff104c51756ee69383bfb2d366c02d663c194870b8001bad9021aef8360405161308591815260200190565b6135d28282611e72565b6132195760405163e2517d3f60e01b81526001600160a01b0382166004820152602481018390526044016111e3565b5f81815260018301602052604081205480156136db575f6136236001836142e7565b85549091505f90613636906001906142e7565b9050808214613695575f865f01828154811061365457613654614217565b905f5260205f200154905080875f01848154811061367457613674614217565b5f918252602080832090910192909255918252600188019052604090208390555b85548690806136a6576136a661432a565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610d83565b5f915050610d83565b5f825f0182815481106136f9576136f9614217565b905f5260205f200154905092915050565b5f5f8051602061435f8339815191528161372485856139af565b9050801561135f575f858152602083905260409020613743908561338e565b50949350505050565b5f61243a83836137d0565b5f5f8051602061435f833981519152816137718585613a47565b9050801561135f575f8581526020839052604090206137439085612f0c565b5f61243a8383613601565b6137a3613ac0565b6131de57604051631afcd79f60e31b815260040160405180910390fd5b6137c861379b565b6131de613ad9565b5f81815260018301602052604081205461381557508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610d83565b505f610d83565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561386957602002820191905f5260205f20905b815481526020019060010190808311613855575b50505050509050919050565b60608261388a5761388582613ae1565b61243a565b81511580156138a157506001600160a01b0384163b155b156138ca57604051639996b31560e01b81526001600160a01b03851660048201526024016111e3565b5092915050565b804710156138fb5760405163cf47918160e01b8152476004820152602481018290526044016111e3565b5f80836001600160a01b0316836040515f6040518083038185875af1925050503d805f8114613945576040519150601f19603f3d011682016040523d82523d5f602084013e61394a565b606091505b509150915081610ffc57610ffc81613ae1565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611269908490613b0a565b5f5f8051602061437f8339815191526139c88484611e72565b6136db575f848152602082815260408083206001600160a01b03871684529091529020805460ff191660011790556139fd3390565b6001600160a01b0316836001600160a01b0316857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001915050610d83565b5f5f8051602061437f833981519152613a608484611e72565b156136db575f848152602082815260408083206001600160a01b0387168085529252808320805460ff1916905551339287917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a46001915050610d83565b5f613ac96131a6565b54600160401b900460ff16919050565b61309261379b565b805115613af15780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b5f8060205f8451602086015f885af180613b29576040513d5f823e3d81fd5b50505f513d91508115613b40578060011415613b4d565b6001600160a01b0384163b155b15610ffc57604051635274afe760e01b81526001600160a01b03851660048201526024016111e3565b5f60208284031215613b86575f80fd5b81356001600160e01b03198116811461243a575f80fd5b6001600160a01b0381168114612ee5575f80fd5b5f60208284031215613bc1575f80fd5b813561243a81613b9d565b5f8083601f840112613bdc575f80fd5b50813567ffffffffffffffff811115613bf3575f80fd5b602083019150836020828501011115613c0a575f80fd5b9250929050565b5f805f805f60808688031215613c25575f80fd5b8535613c3081613b9d565b94506020860135613c4081613b9d565b935060408601359250606086013567ffffffffffffffff811115613c62575f80fd5b613c6e88828901613bcc565b969995985093965092949392505050565b5f805f60608486031215613c91575f80fd5b8335613c9c81613b9d565b92506020840135613cac81613b9d565b929592945050506040919091013590565b5f60208284031215613ccd575f80fd5b5035919050565b5f8060408385031215613ce5575f80fd5b823591506020830135613cf781613b9d565b809150509250929050565b5f8060208385031215613d13575f80fd5b823567ffffffffffffffff811115613d29575f80fd5b613d3585828601613bcc565b90969095509350505050565b5f805f60608486031215613d53575f80fd5b833592506020840135613d6581613b9d565b91506040840135613d7581613b9d565b809150509250925092565b8015158114612ee5575f80fd5b5f805f805f8060a08789031215613da2575f80fd5b863595506020870135613db481613d80565b94506040870135613dc481613b9d565b93506060870135613dd481613b9d565b9250608087013567ffffffffffffffff811115613def575f80fd5b613dfb89828a01613bcc565b979a9699509497509295939492505050565b5f8060408385031215613e1e575f80fd5b50508035926020909101359150565b803563ffffffff81168114613e40575f80fd5b919050565b5f805f8060808587031215613e58575f80fd5b8435613e6381613b9d565b935060208501356001600160e01b0381168114613e7e575f80fd5b9250613e8c60408601613e2d565b9150613e9a60608601613e2d565b905092959194509250565b602080825282518282018190525f9190848201906040850190845b81811015613ee55783516001600160a01b031683529284019291840191600101613ec0565b50909695505050505050565b5f8060408385031215613f02575f80fd5b8235613f0d81613b9d565b946020939093013593505050565b5f8060408385031215613f2c575f80fd5b8235613f3781613b9d565b91506020830135613cf781613b9d565b5f8060408385031215613f58575f80fd5b8235613f6381613b9d565b91506020830135613cf781613d80565b5f60208284031215613f83575f80fd5b815161243a81613d80565b5f60208284031215613f9e575f80fd5b815161243a81613b9d565b634e487b7160e01b5f52601160045260245ffd5b5f81613fcb57613fcb613fa9565b505f190190565b5f60208284031215613fe2575f80fd5b5051919050565b80820180821115610d8357610d83613fa9565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff8111828210171561403357614033613ffc565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561406257614062613ffc565b604052919050565b5f805f805f805f805f6101208a8c031215614083575f80fd5b61408d8a35613b9d565b8935985061409e60208b0135613b9d565b60208a013597506140b260408b0135613b9d565b60408a013596506140c660608b0135613b9d565b60608a013595506140da60808b0135613b9d565b60808a013594506140ee60a08b0135613b9d565b60a08a0135935061410260c08b0135613b9d565b60c08a0135925060e08a0135915067ffffffffffffffff6101008b01351115614129575f80fd5b8a601f6101008c01358c01011261413e575f80fd5b67ffffffffffffffff6101008b01358b0135111561415e5761415e613ffc565b61417560206101008c01358c013560051b01614039565b6101008b01358b0180358083526020808401939260069290921b909101018d101561419e575f80fd5b60206101008d01358d01015b6101008d01358d01803560061b01602001811015614204576040818f0312156141d1575f80fd5b6141d9614010565b813581526141ea6020830135613b9d565b6020828101358282015290845292909201916040016141aa565b5080925050509295985092959850929598565b634e487b7160e01b5f52603260045260245ffd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b602081525f61135f60208301848661422b565b83815260018060a01b0383166020820152606060408201525f82518060608401528060208501608085015e5f608082850101526080601f19601f830116840101915050949350505050565b6001600160a01b038581168252841660208201526060604082018190525f906142dd908301848661422b565b9695505050505050565b81810381811115610d8357610d83613fa9565b5f600160ff1b820161430e5761430e613fa9565b505f0390565b5f82518060208501845e5f920191825250919050565b634e487b7160e01b5f52603160045260245ffdfe627f9e4ac2dadb64d045e7e6333c09f39ed34e0e066957955d0052b46d2e83e8c1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e8237170593200002dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220a4abd3b773c3b2209af423d73616a077f3c6a84e29bd5fc241febf1346ddba7b64736f6c63430008190033","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/0x0000000615B2771511dAa693aC07BE5622869E01/","decoded_constructor_args":[["Mellow",{"internalType":"string","name":"name_","type":"string"}],["1",{"internalType":"uint256","name":"version_","type":"uint256"}],["0xBB92A7B9695750e1234BaB18F83b73686dd09854",{"internalType":"address","name":"depositQueueFactory_","type":"address"}],["0xfe76b5fd238553D65Ce6dd0A572C0fda629F8421",{"internalType":"address","name":"redeemQueueFactory_","type":"address"}],["0x75FE0d73d3C64cdC1C6449D9F977Be6857c4d011",{"internalType":"address","name":"subvaultFactory_","type":"address"}],["0x04B30b1e98950e6A13550d84e991bE0d734C2c61",{"internalType":"address","name":"verifierFactory_","type":"address"}]],"compiler_version":"0.8.25+commit.b61c2a91","is_verified_via_verifier_alliance":false,"verified_at":"2025-09-10T19:11:13.767863Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x610160604052348015610010575f80fd5b506040516148af3803806148af83398101604081905261002f91610282565b85858585838387878383818161004361011b565b60408051808201909152600981526813595b1b1bddd050d360ba1b602082015261006e9083836101b8565b60805261007961011b565b505050506100b16040518060400160405280600b81526020016a5661756c744d6f64756c6560a81b81525085856101b860201b60201c565b60e0526001600160a01b0391821660a0521660c052505060408051808201909152600b81526a53686172654d6f64756c6560a81b60208201526100f59085856101b8565b610140526001600160a01b03918216610100521661012052506103f39650505050505050565b5f610124610229565b805490915068010000000000000000900460ff16156101565760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101b55780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60ff5f1b1960018585856040516020016101d59392919061038c565b604051602081830303815290604052805190602001205f1c6101f791906103d4565b60405160200161020991815260200190565b604051602081830303815290604052805190602001201690509392505050565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005b92915050565b634e487b7160e01b5f52604160045260245ffd5b80516001600160a01b038116811461027d575f80fd5b919050565b5f805f805f8060c08789031215610297575f80fd5b86516001600160401b03808211156102ad575f80fd5b818901915089601f8301126102c0575f80fd5b8151818111156102d2576102d2610253565b604051601f8201601f19908116603f011681019083821181831017156102fa576102fa610253565b816040528281528c6020848701011115610312575f80fd5b8260208601602083015e5f60208483010152809a5050505050506020870151945061033f60408801610267565b935061034d60608801610267565b925061035b60808801610267565b915061036960a08801610267565b90509295509295509295565b5f81518060208401855e5f93019283525090919050565b7f6d656c6c6f772e666c657869626c652d7661756c74732e73746f726167652e0081525f6103c66103c0601f840187610375565b85610375565b928352505060200192915050565b8181038181111561024d57634e487b7160e01b5f52601160045260245ffd5b60805160a05160c05160e0516101005161012051610140516143f46104bb5f395f612eea01525f81816109750152611c8701525f818161078b0152611cad01525f818161119301528181611591015281816118bd01528181611b4d015281816123ac01528181612447015281816124f2015261331701525f818161064a015281816116cc01526126e501525f81816109e6015281816117f0015261253301525f8181611388015281816115c6015281816123ec015281816130c5015261314e01526143f45ff3fe6080604052600436106103ed575f3560e01c8063850260ff1161020a578063b014f4451161011e578063e4f8d0e6116100a8578063eb56d52d11610078578063eb56d52d14610cc3578063ec0f580014610ce2578063ecef475f14610d01578063f31cb0c614610d20578063f68e730414610d3f575f80fd5b8063e4f8d0e614610c33578063e6c8cd9f14610c52578063e6ed8d7414610c71578063e984f35314610ca4575f80fd5b8063ca15c873116100ee578063ca15c87314610b8f578063d0fb020314610bae578063d27d250314610bc2578063d547741f14610be1578063d8b07a6514610c00575f80fd5b8063b014f44514610aff578063b1a62e3b14610b1e578063b2b71a2714610b51578063b91c935c14610b70575f80fd5b80639ff2cb9d1161019f578063a3246ad31161016f578063a3246ad314610a4e578063a35f620a14610a7a578063a567fb4714610a8e578063aa9239f514610aad578063adf167ce14610acc575f80fd5b80639ff2cb9d146109d5578063a0aead4d14610a08578063a217fddf14610a1c578063a2cb31e514610a2f575f80fd5b806392e6ece5116101da57806392e6ece5146109455780639662d42914610964578063974d942e146109975780639bd0911b146109b6575f80fd5b8063850260ff146108c95780638679ed7c146108e85780639010d07c1461090757806391d1485414610926575f80fd5b8063419a2053116103015780635636d54911610296578063651ae6c711610266578063651ae6c71461081c578063663ade061461084f5780636b8b1ccd146108825780637dc0d1d0146108965780638333903b146108aa575f80fd5b80635636d549146107ad57806358b7bf30146107c15780635c60173d146107f45780635d66b00a14610808575f80fd5b80634b694b96116102d15780634b694b961461071d5780634b812c1f1461073c57806352278ab71461075b57806352fd42541461077a575f80fd5b8063419a2053146106b7578063439fab91146106cb57806347842663146106ea5780634a46b4cf146106fe575f80fd5b80632f2ff15d1161038257806336568abe1161035257806336568abe146105fb578063370488161461061a578063387db78f146106395780633d4304e6146106845780634015b2a8146106a3575f80fd5b80632f2ff15d146105765780632f8ecb50146105955780633314bbb9146105b45780633471b337146105e7575f80fd5b806317cbc8b1116103bd57806317cbc8b1146104d25780631c14724f146104f15780631ca0027a14610510578063248a9ca314610557575f80fd5b806301ffc9a7146103f8578063040bee6d1461042c57806313cb953a1461044d578063150b7a021461048e575f80fd5b366103f457005b5f80fd5b348015610403575f80fd5b50610417610412366004613b76565b610d5f565b60405190151581526020015b60405180910390f35b348015610437575f80fd5b5061044b610446366004613bb1565b610d89565b005b348015610458575f80fd5b506104807f32a781031f04cc60b32394e40124d1e87f54273bf26d0532a115a424f6a9329881565b604051908152602001610423565b348015610499575f80fd5b506104b96104a8366004613c11565b630a85bd0160e11b95945050505050565b6040516001600160e01b03199091168152602001610423565b3480156104dd575f80fd5b5061044b6104ec366004613c7f565b610fa9565b3480156104fc575f80fd5b5061048061050b366004613bb1565b611002565b34801561051b575f80fd5b5061054861052a366004613cbd565b60408051602080820183525f90915281519081019091529054815290565b60405190518152602001610423565b348015610562575f80fd5b50610480610571366004613cbd565b61112b565b348015610581575f80fd5b5061044b610590366004613cd4565b61114b565b3480156105a0575f80fd5b5061044b6105af366004613bb1565b611167565b3480156105bf575f80fd5b506104807f68895691ff006f290ca74825ce06ed17fffab55af49f0274f49b7424f752583a81565b3480156105f2575f80fd5b50610480611224565b348015610606575f80fd5b5061044b610615366004613cd4565b611236565b348015610625575f80fd5b5061044b610634366004613bb1565b61126e565b348015610644575f80fd5b5061066c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610423565b34801561068f575f80fd5b5061066c61069e366004613bb1565b6112e8565b3480156106ae575f80fd5b5061066c611367565b3480156106c2575f80fd5b50610480611382565b3480156106d6575f80fd5b5061044b6106e5366004613d02565b6113b1565b3480156106f5575f80fd5b5061066c61158e565b348015610709575f80fd5b50610417610718366004613cbd565b6115c0565b348015610728575f80fd5b50610417610737366004613bb1565b6115eb565b348015610747575f80fd5b5061066c610756366004613d41565b61167a565b348015610766575f80fd5b50610480610775366004613bb1565b611959565b348015610785575f80fd5b5061066c7f000000000000000000000000000000000000000000000000000000000000000081565b3480156107b8575f80fd5b5061066c611985565b3480156107cc575f80fd5b506104807fb557d53a2e72d8333ffa3bf2f556678becb5e995b0e25b7dca354627e550c08f81565b3480156107ff575f80fd5b5061066c6119a0565b348015610813575f80fd5b506104806119a9565b348015610827575f80fd5b506104807f9a4c49d6fb9452bbfe187968075d0fac7d7202d2b7f731d8cffbce9cf66756b281565b34801561085a575f80fd5b506104807ff610639f4b9b8986f875fcb4e49486da5c7aa449a6942b5013fabd061e9b9fff81565b34801561088d575f80fd5b50610480611b18565b3480156108a1575f80fd5b5061066c611b2a565b3480156108b5575f80fd5b506104176108c4366004613bb1565b611b45565b3480156108d4575f80fd5b5061044b6108e3366004613d8d565b611b73565b3480156108f3575f80fd5b50610417610902366004613bb1565b611e20565b348015610912575f80fd5b5061066c610921366004613e0d565b611e4d565b348015610931575f80fd5b50610417610940366004613cd4565b611e72565b348015610950575f80fd5b5061041761095f366004613bb1565b611ea8565b34801561096f575f80fd5b5061066c7f000000000000000000000000000000000000000000000000000000000000000081565b3480156109a2575f80fd5b5061044b6109b1366004613e45565b611ed5565b3480156109c1575f80fd5b5061066c6109d0366004613cbd565b6123a4565b3480156109e0575f80fd5b5061066c7f000000000000000000000000000000000000000000000000000000000000000081565b348015610a13575f80fd5b506104806123d2565b348015610a27575f80fd5b506104805f81565b348015610a3a575f80fd5b50610480610a49366004613cbd565b6123e6565b348015610a59575f80fd5b50610a6d610a68366004613cbd565b612411565b6040516104239190613ea5565b348015610a85575f80fd5b50610480612441565b348015610a99575f80fd5b50610417610aa8366004613bb1565b61246e565b348015610ab8575f80fd5b5061066c610ac7366004613cbd565b612484565b348015610ad7575f80fd5b506104807f85c2023fdfb1e93dedf5d18f9bc0e79347e071d12740ba71aeb84a4fcbdc4b7981565b348015610b0a575f80fd5b5061044b610b19366004613c7f565b61249a565b348015610b29575f80fd5b506104807f6788636e7899d6d227901dc9f8c4c785401c0991724cf908dc65388af686da6f81565b348015610b5c575f80fd5b5061044b610b6b366004613bb1565b6124c5565b348015610b7b575f80fd5b5061066c610b8a366004613ef1565b612884565b348015610b9a575f80fd5b50610480610ba9366004613cbd565b6128b2565b348015610bb9575f80fd5b5061066c6128d6565b348015610bcd575f80fd5b5061044b610bdc366004613cbd565b6128f1565b348015610bec575f80fd5b5061044b610bfb366004613cd4565b612a98565b348015610c0b575f80fd5b506104807f6618a6d92147bbcacfb2ef2375976fc4c529eeeaeb72a66048296571370c694681565b348015610c3e575f80fd5b5061044b610c4d366004613f1b565b612ab4565b348015610c5d575f80fd5b5061044b610c6c366004613c7f565b612b5d565b348015610c7c575f80fd5b506104807f407fc42eadf1aba68b1d4a8c3c4aa2e8b6beac7957623f3694d0ad77bfb70e0681565b348015610caf575f80fd5b5061044b610cbe366004613c7f565b612b88565b348015610cce575f80fd5b5061044b610cdd366004613f47565b612bc5565b348015610ced575f80fd5b5061044b610cfc366004613bb1565b612c79565b348015610d0c575f80fd5b5061044b610d1b366004613cbd565b612cea565b348015610d2b575f80fd5b5061044b610d3a366004613bb1565b612d58565b348015610d4a575f80fd5b506104805f8051602061433f83398151915281565b5f6001600160e01b03198216635a05180f60e01b1480610d835750610d8382612ea7565b92915050565b7f9a4c49d6fb9452bbfe187968075d0fac7d7202d2b7f731d8cffbce9cf66756b2610db381612edb565b816001600160a01b031663c2f218966040518163ffffffff1660e01b8152600401602060405180830381865afa158015610def573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e139190613f73565b610e3057604051631dd2188d60e31b815260040160405180910390fd5b5f826001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e6d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e919190613f8e565b90505f610e9c612ee8565b6001600160a01b0383165f908152600a820160205260409020909150610ec29085612f0c565b610edf57604051631dd2188d60e31b815260040160405180910390fd5b6001600160a01b038085165f9081526008830160209081526040808320805460ff191690559285168252600a8401905220610f1990612f20565b5f03610f2e57610f2c600b820183612f0c565b505b6001600160a01b0384165f908152600782016020526040812080546001600160a01b0319169055600582018054909190610f6790613fbd565b909155506040516001600160a01b0380841691908616907faf660c1b265f07536d70b577e6dac1fed859eae81dca40591155a8fa2294553d905f90a350505050565b7f68895691ff006f290ca74825ce06ed17fffab55af49f0274f49b7424f752583a610fd381612edb565b610fdb612f29565b610fe6848484612f60565b610ffc60015f8051602061439f83398151915255565b50505050565b5f8061100c612ee8565b9050600b81015f61101c82612f20565b90505f5b81811015611122575f61103384836130a5565b6001600160a01b0381165f908152600a87016020526040812091925061105882612f20565b90505f5b81811015611112575f61106f84836130a5565b6001600160a01b0381165f90815260088b01602052604090205490915060ff161561110957604051638903ab9d60e01b81526001600160a01b038c81166004830152821690638903ab9d90602401602060405180830381865afa1580156110d8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110fc9190613fd2565b611106908b613fe9565b99505b5060010161105c565b5050600190920191506110209050565b50505050919050565b5f9081525f8051602061437f833981519152602052604090206001015490565b6111548261112b565b61115d81612edb565b610ffc83836130b0565b7ff610639f4b9b8986f875fcb4e49486da5c7aa449a6942b5013fabd061e9b9fff61119181612edb565b7f00000000000000000000000000000000000000000000000000000000000000006111bf6001820184612f0c565b6111ec57604051635c6a489f60e01b81526001600160a01b03841660048201526024015b60405180910390fd5b6040516001600160a01b038416907f95067a3324c952e40449419ed59015549ae2c2b2c5988efb9bdaaf33baf6f793905f90a2505050565b5f61122d612ee8565b60050154905090565b6001600160a01b038116331461125f5760405163334bd91960e11b815260040160405180910390fd5b611269828261312a565b505050565b5f8051602061433f83398151915261128581612edb565b8161128e612ee8565b60030180546001600160a01b0319166001600160a01b0392831617905560405160018152908316907f59dc533a8345ccff036afdd89363a87154a5e6c51ff4fc507fc1865bb925438e906020015b60405180910390a25050565b5f806112f2612ee8565b6001600160a01b038085165f908152600783016020526040902054919250168061135d576001600160a01b0384165f90815260088301602052604090205460ff1661134a5760048201546001600160a01b031661135f565b60038201546001600160a01b031661135f565b805b949350505050565b5f611370612ee8565b600401546001600160a01b0316919050565b5f6113ac7f0000000000000000000000000000000000000000000000000000000000000000612f20565b905090565b5f6113ba6131a6565b805490915060ff600160401b820416159067ffffffffffffffff165f811580156113e15750825b90505f8267ffffffffffffffff1660011480156113fd5750303b155b90508115801561140b575080155b156114295760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561145357845460ff60401b1916600160401b1785555b5f805f805f805f805f8f8f81019061146b919061406a565b9850985098509850985098509850985098506114856131ce565b61148e896131e0565b61149c88888787878761321d565b6114a5866132e6565b5f5b81518110156114fc576114f38282815181106114c5576114c5614217565b60200260200101515f01518383815181106114e2576114e2614217565b6020026020010151602001516130b0565b506001016114a7565b505050505050505050507f5e399709a9ff1709f6f6be7268c8e5c3eeaa9da9cd9797e78f07ef287c3717fe8787604051611537929190614253565b60405180910390a1831561158557845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000005b546001600160a01b0316919050565b5f610d837f000000000000000000000000000000000000000000000000000000000000000083613356565b5f610d83826115f8612ee8565b600a015f856001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611638573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061165c9190613f8e565b6001600160a01b0316815260208101919091526040015f209061336d565b5f7f85c2023fdfb1e93dedf5d18f9bc0e79347e071d12740ba71aeb84a4fcbdc4b796116a581612edb565b6116ad612f29565b6040516302910f8b60e31b81526001600160a01b0384811660048301527f000000000000000000000000000000000000000000000000000000000000000016906314887c5890602401602060405180830381865afa158015611711573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117359190613f73565b61175d5760405163d0b5c30560e01b81526001600160a01b03841660048201526024016111e3565b306001600160a01b0316836001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117a3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117c79190613f8e565b6001600160a01b0316146117ee57604051631dd2188d60e31b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166346fbcbb2868686306040516020016118479291906001600160a01b0392831681529116602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161187493929190614266565b6020604051808303815f875af1158015611890573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118b49190613f8e565b91506118e360017f0000000000000000000000000000000000000000000000000000000000000000018361338e565b50826001600160a01b0316846001600160a01b0316836001600160a01b03167fae0bbc337ca4971dd982cb61e17432f83cf2e5647ad778f7db9ff18efd77a2118860405161193391815260200190565b60405180910390a461195160015f8051602061439f83398151915255565b509392505050565b5f610d83611965612ee8565b6001600160a01b0384165f908152600a9190910160205260409020612f20565b5f61198e612ee8565b600301546001600160a01b0316919050565b5f6115b1612ee8565b5f803390505f816001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119eb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a0f9190613f8e565b90505f611a1a612ee8565b6001600160a01b0383165f908152600a820160205260409020909150611a40908461336d565b1580611a6557506001600160a01b0383165f90815260088201602052604090205460ff165b15611a8357604051631dd2188d60e31b815260040160405180910390fd5b5f611a8d846112e8565b90506001600160a01b038116611ab057611aa783306133a2565b94505050505090565b604051630af5049b60e11b81526001600160a01b0384811660048301528216906315ea093690602401602060405180830381865afa158015611af4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611aa79190613fd2565b5f611b21612ee8565b60060154905090565b5f611b33612ee8565b600201546001600160a01b0316919050565b5f610d8360017f0000000000000000000000000000000000000000000000000000000000000000018361336d565b611b7b612f29565b7f6788636e7899d6d227901dc9f8c4c785401c0991724cf908dc65388af686da6f611ba581612edb565b5f611bae612ee8565b6002810154604051634df48c7360e11b81526001600160a01b038881166004830152929350911690639be918e690602401602060405180830381865afa158015611bfa573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c1e9190613f73565b611c465760405163ee84f40b60e01b81526001600160a01b03861660048201526024016111e3565b5f81600501546001611c589190613fe9565b90508160060154811115611c7f5760405163082d389160e31b815260040160405180910390fd5b5f88611cab577f0000000000000000000000000000000000000000000000000000000000000000611ccd565b7f00000000000000000000000000000000000000000000000000000000000000005b6001600160a01b03166346fbcbb28b8a8a308b8b604051602001611cf494939291906142b1565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401611d2193929190614266565b6020604051808303815f875af1158015611d3d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d619190613f8e565b600584018390556001600160a01b0388165f908152600a850160205260409020909150611d8e908261338e565b50611d9c600b84018861338e565b506001600160a01b038181165f818152600886016020908152604091829020805460ff19168e15159081179091559151918252928a16927f8138cea23ce1869026f924550085f1d5666d82c6c948c921cf9003cac6bfea9c910160405180910390a350505050611e1860015f8051602061439f83398151915255565b505050505050565b5f611e29612ee8565b6001600160a01b039092165f90815260099290920160205250604090205460ff1690565b5f8281525f8051602061435f83398151915260208190526040822061135f90846130a5565b5f9182525f8051602061437f833981519152602090815260408084206001600160a01b0393909316845291905290205460ff1690565b5f611eb1612ee8565b6001600160a01b039092165f90815260089290920160205250604090205460ff1690565b611edd612f29565b5f611ee6612ee8565b60028101549091506001600160a01b0316336001600160a01b031614611f1f57604051631dd2188d60e31b815260040160405180910390fd5b80546001820154604051630cd9f5f560e11b81523060048201526001600160a01b0392831692909116905f9082906319b3ebea90602401602060405180830381865afa158015611f71573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f959190613f8e565b6001600160a01b0316886001600160a01b031603612242575f826001600160a01b031663469048406040518163ffffffff1660e01b8152600401602060405180830381865afa158015611fea573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061200e9190613f8e565b604051639d66201b60e01b81526001600160a01b0380831660048301529192508185169163e0e193a29130918d918d918a1690639d66201b90602401602060405180830381865afa158015612065573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120899190613fd2565b896001600160a01b0316633a98ef396040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120c5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120e99190613fd2565b6120f391906142e7565b6040516001600160e01b031960e087901b1681526001600160a01b0394851660048201529390921660248401526001600160e01b031660448301526064820152608401602060405180830381865afa158015612151573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121759190613fd2565b915081156121db576040516340c10f1960e01b81526001600160a01b038281166004830152602482018490528516906340c10f19906044015f604051808303815f87803b1580156121c4575f80fd5b505af11580156121d6573d5f803e3d5ffd5b505050505b604051634d71303160e11b81526001600160a01b038a811660048301526001600160e01b038a166024830152841690639ae26062906044015f604051808303815f87803b15801561222a575f80fd5b505af115801561223c573d5f803e3d5ffd5b50505050505b5f61224b612ee8565b6001600160a01b038a165f908152600a9190910160205260408120915061227182612f20565b90505f5b81811015612329575f61228884836130a5565b6001600160a01b0381165f81815260088b0160205260409020549192509063b8c5ea8a908d9060ff166122bb578b6122bd565b8c5b6040516001600160e01b031960e085901b1681526001600160e01b03909216600483015263ffffffff1660248201526044015f604051808303815f87803b158015612306575f80fd5b505af1158015612318573d5f803e3d5ffd5b505060019093019250612275915050565b506040805163ffffffff808b168252891660208201529081018490526001600160e01b038a16906001600160a01b038c16907f24bbf515a701fcb7a993b1e8c3f201ab4e608f7b85c61b1f8cc0e19dc9d526539060600160405180910390a3505050505050610ffc60015f8051602061439f83398151915255565b5f610d8360017f000000000000000000000000000000000000000000000000000000000000000001836130a5565b5f6113ac6123de612ee8565b600b01612f20565b5f610d837f0000000000000000000000000000000000000000000000000000000000000000836130a5565b5f8181525f8051602061435f833981519152602081905260409091206060919061243a90613448565b9392505050565b5f6113ac7f0000000000000000000000000000000000000000000000000000000000000000600101612f20565b5f610d838261247b612ee8565b600b019061336d565b5f610d8382612491612ee8565b600b01906130a5565b3330146124ba57604051631dd2188d60e31b815260040160405180910390fd5b611269838383612f60565b7fb557d53a2e72d8333ffa3bf2f556678becb5e995b0e25b7dca354627e550c08f6124ef81612edb565b5f7f00000000000000000000000000000000000000000000000000000000000000006040516302910f8b60e31b81526001600160a01b0385811660048301529192507f0000000000000000000000000000000000000000000000000000000000000000909116906314887c5890602401602060405180830381865afa15801561257a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061259e9190613f73565b6125c65760405163d0b5c30560e01b81526001600160a01b03841660048201526024016111e3565b306001600160a01b0316836001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561260c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126309190613f8e565b6001600160a01b0316146126625760405163d034fb7960e01b81526001600160a01b03841660048201526024016111e3565b5f836001600160a01b0316632b7ac3f36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561269f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126c39190613f8e565b6040516302910f8b60e31b81526001600160a01b0380831660048301529192507f0000000000000000000000000000000000000000000000000000000000000000909116906314887c5890602401602060405180830381865afa15801561272c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127509190613f73565b6127785760405163d0b5c30560e01b81526001600160a01b03821660048201526024016111e3565b306001600160a01b0316816001600160a01b031663fbfa77cf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127e29190613f8e565b6001600160a01b03161461280957604051631dd2188d60e31b815260040160405180910390fd5b612816600183018561338e565b61283e57604051638cd80ed360e01b81526001600160a01b03851660048201526024016111e3565b806001600160a01b0316846001600160a01b03167ff75f2e4922769fc299f8f612c31f2d1f8ea0e6fa4c82fdb143bf9c8a070c974c60405160405180910390a350505050565b5f61243a82612891612ee8565b6001600160a01b0386165f908152600a9190910160205260409020906130a5565b5f8181525f8051602061435f83398151915260208190526040822061243a90612f20565b5f6128df612ee8565b600101546001600160a01b0316919050565b5f3390505f816001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612932573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129569190613f8e565b90505f612961612ee8565b90506129908361296f612ee8565b6001600160a01b0385165f908152600a91909101602052604090209061336d565b6129ad57604051631dd2188d60e31b815260040160405180910390fd5b5f6129b7846112e8565b90506001600160a01b03811615612a1b576040516001600160a01b038416602482015260448101869052612a1990829060640160408051601f198184030181529190526020810180516001600160e01b03166330f736c160e21b179052613454565b505b6001600160a01b0384165f90815260088301602052604090205460ff16612a4757612a478385876134c6565b604080518681526001600160a01b03838116602083015280861692908716917fc23ec549723039bc8a35cac0162f81095410795793f7730887eb1a0e06ef5476910160405180910390a35050505050565b612aa18261112b565b612aaa81612edb565b610ffc838361312a565b5f8051602061433f833981519152612acb81612edb565b6001600160a01b038316612af25760405163d92e233d60e01b815260040160405180910390fd5b81612afb612ee8565b6001600160a01b038581165f818152600793909301602052604080842080546001600160a01b03191695841695909517909455925190851692917f329d0838d5265a7d9d220b95803da511a475abe411dc4df364c1d1b8b923cdf991a3505050565b333014612b7d57604051631dd2188d60e31b815260040160405180910390fd5b611269838383613509565b7f32a781031f04cc60b32394e40124d1e87f54273bf26d0532a115a424f6a93298612bb281612edb565b612bba612f29565b610fe6848484613509565b7f6618a6d92147bbcacfb2ef2375976fc4c529eeeaeb72a66048296571370c6946612bef81612edb565b612bf8836115eb565b612c1557604051631dd2188d60e31b815260040160405180910390fd5b81612c1e612ee8565b6001600160a01b0385165f8181526009929092016020526040808320805460ff191694151594909417909355915184151592917f0adde9ce751962c98f81b39c8c220e3e355e0427d8f497ad6533849e0887543d91a3505050565b5f8051602061433f833981519152612c9081612edb565b81612c99612ee8565b60040180546001600160a01b0319166001600160a01b039283161790556040515f8152908316907f59dc533a8345ccff036afdd89363a87154a5e6c51ff4fc507fc1865bb925438e906020016112dc565b7f407fc42eadf1aba68b1d4a8c3c4aa2e8b6beac7957623f3694d0ad77bfb70e06612d1481612edb565b81612d1d612ee8565b600601556040518281527f7abc95a9228ca8caf8cbd0d9add729de5d2032bb1792bb6c5faff0f175f1bd509060200160405180910390a15050565b5f612d61612ee8565b9050600b81015f612d7182612f20565b90505f5b81811015612e6d575f612d8884836130a5565b6001600160a01b0381165f908152600a870160205260408120919250612dad82612f20565b90505f5b81811015612e5d575f612dc484836130a5565b6001600160a01b0381165f90815260088b01602052604090205490915060ff1615612e5457604051630f41a04d60e11b81526001600160a01b038b81166004830152821690631e83409a906024016020604051808303815f875af1158015612e2e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e529190613f73565b505b50600101612db1565b505060019092019150612d759050565b506040516001600160a01b038516907f3a97aa17a51b3fa88e27cdce48823bea308838ed5ea8015ae0598abb1288954b905f90a250505050565b5f6001600160e01b03198216637965db0b60e01b1480610d8357506301ffc9a760e01b6001600160e01b0319831614610d83565b612ee581336135c8565b50565b7f000000000000000000000000000000000000000000000000000000000000000090565b5f61243a836001600160a01b038416613601565b5f610d83825490565b5f8051602061439f833981519152805460011901612f5a57604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b612f6861158e565b6001600160a01b031663fea34d988484612f81856142fa565b6040516001600160e01b031960e086901b1681526001600160a01b03938416600482015292909116602483015260448201526064015f604051808303815f87803b158015612fcd575f80fd5b505af1158015612fdf573d5f803e3d5ffd5b50506040516387cd303d60e01b81526001600160a01b03858116600483015260248201859052861692506387cd303d91506044015f604051808303815f87803b15801561302a575f80fd5b505af115801561303c573d5f803e3d5ffd5b50505050826001600160a01b0316826001600160a01b03167f409f90100010c596e4859c24945544ea3430a899b81522dadfd9671b9bc1a4028360405161308591815260200190565b60405180910390a3505050565b60015f8051602061439f83398151915255565b5f61243a83836136e4565b5f6130bb838361370a565b15613122576130ea7f00000000000000000000000000000000000000000000000000000000000000008461374c565b1561311a5760405183907fea0f1c470fa813c725756c036120b6688028969f5afbc607918fcd1ff9229435905f90a25b506001610d83565b505f92915050565b5f6131358383613757565b1561312257613143836128b2565b5f0361311a576131737f000000000000000000000000000000000000000000000000000000000000000084613790565b5060405183907f4c9a714f78b79aa08074addab7cbdb196cccdf6d67efbf0b99914db8a6b08e73905f90a2506001610d83565b5f807ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00610d83565b6131d661379b565b6131de6137c0565b565b6131e861379b565b6001600160a01b03811661320f5760405163d92e233d60e01b815260040160405180910390fd5b6132195f826130b0565b5050565b61322561379b565b6001600160a01b038616158061324257506001600160a01b038516155b8061325457506001600160a01b038416155b156132725760405163d92e233d60e01b815260040160405180910390fd5b5f61327b612ee8565b80546001600160a01b03199081166001600160a01b03998a161782556001820180548216988a16989098179097556002810180548816968916969096179095555060038401805486169387169390931790925560048301805490941694169390931790915560060155565b6132ee61379b565b6001600160a01b0381166133155760405163d92e233d60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000080546001600160a01b0319166001600160a01b0392909216919091179055565b5f818152600183016020526040812054151561243a565b6001600160a01b0381165f908152600183016020526040812054151561243a565b5f61243a836001600160a01b0384166137d0565b5f73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038416016133d957506001600160a01b03811631610d83565b6040516370a0823160e01b81526001600160a01b0383811660048301528416906370a0823190602401602060405180830381865afa15801561341d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134419190613fd2565b9050610d83565b60605f61243a8361381c565b60605f80846001600160a01b0316846040516134709190614314565b5f60405180830381855af49150503d805f81146134a8576040519150601f19603f3d011682016040523d82523d5f602084013e6134ad565b606091505b50915091506134bd858383613875565b95945050505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038416016134f55761126982826138d1565b6112696001600160a01b038416838361395d565b61351161158e565b604051631fd469b360e31b81526001600160a01b038581166004830152848116602483015260448201849052919091169063fea34d98906064015f604051808303815f87803b158015613562575f80fd5b505af1158015613574573d5f803e3d5ffd5b505050506135838284836134c6565b826001600160a01b0316826001600160a01b03167f7ceb394e9ff104c51756ee69383bfb2d366c02d663c194870b8001bad9021aef8360405161308591815260200190565b6135d28282611e72565b6132195760405163e2517d3f60e01b81526001600160a01b0382166004820152602481018390526044016111e3565b5f81815260018301602052604081205480156136db575f6136236001836142e7565b85549091505f90613636906001906142e7565b9050808214613695575f865f01828154811061365457613654614217565b905f5260205f200154905080875f01848154811061367457613674614217565b5f918252602080832090910192909255918252600188019052604090208390555b85548690806136a6576136a661432a565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610d83565b5f915050610d83565b5f825f0182815481106136f9576136f9614217565b905f5260205f200154905092915050565b5f5f8051602061435f8339815191528161372485856139af565b9050801561135f575f858152602083905260409020613743908561338e565b50949350505050565b5f61243a83836137d0565b5f5f8051602061435f833981519152816137718585613a47565b9050801561135f575f8581526020839052604090206137439085612f0c565b5f61243a8383613601565b6137a3613ac0565b6131de57604051631afcd79f60e31b815260040160405180910390fd5b6137c861379b565b6131de613ad9565b5f81815260018301602052604081205461381557508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610d83565b505f610d83565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561386957602002820191905f5260205f20905b815481526020019060010190808311613855575b50505050509050919050565b60608261388a5761388582613ae1565b61243a565b81511580156138a157506001600160a01b0384163b155b156138ca57604051639996b31560e01b81526001600160a01b03851660048201526024016111e3565b5092915050565b804710156138fb5760405163cf47918160e01b8152476004820152602481018290526044016111e3565b5f80836001600160a01b0316836040515f6040518083038185875af1925050503d805f8114613945576040519150601f19603f3d011682016040523d82523d5f602084013e61394a565b606091505b509150915081610ffc57610ffc81613ae1565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611269908490613b0a565b5f5f8051602061437f8339815191526139c88484611e72565b6136db575f848152602082815260408083206001600160a01b03871684529091529020805460ff191660011790556139fd3390565b6001600160a01b0316836001600160a01b0316857f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a46001915050610d83565b5f5f8051602061437f833981519152613a608484611e72565b156136db575f848152602082815260408083206001600160a01b0387168085529252808320805460ff1916905551339287917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a46001915050610d83565b5f613ac96131a6565b54600160401b900460ff16919050565b61309261379b565b805115613af15780518082602001fd5b60405163d6bda27560e01b815260040160405180910390fd5b5f8060205f8451602086015f885af180613b29576040513d5f823e3d81fd5b50505f513d91508115613b40578060011415613b4d565b6001600160a01b0384163b155b15610ffc57604051635274afe760e01b81526001600160a01b03851660048201526024016111e3565b5f60208284031215613b86575f80fd5b81356001600160e01b03198116811461243a575f80fd5b6001600160a01b0381168114612ee5575f80fd5b5f60208284031215613bc1575f80fd5b813561243a81613b9d565b5f8083601f840112613bdc575f80fd5b50813567ffffffffffffffff811115613bf3575f80fd5b602083019150836020828501011115613c0a575f80fd5b9250929050565b5f805f805f60808688031215613c25575f80fd5b8535613c3081613b9d565b94506020860135613c4081613b9d565b935060408601359250606086013567ffffffffffffffff811115613c62575f80fd5b613c6e88828901613bcc565b969995985093965092949392505050565b5f805f60608486031215613c91575f80fd5b8335613c9c81613b9d565b92506020840135613cac81613b9d565b929592945050506040919091013590565b5f60208284031215613ccd575f80fd5b5035919050565b5f8060408385031215613ce5575f80fd5b823591506020830135613cf781613b9d565b809150509250929050565b5f8060208385031215613d13575f80fd5b823567ffffffffffffffff811115613d29575f80fd5b613d3585828601613bcc565b90969095509350505050565b5f805f60608486031215613d53575f80fd5b833592506020840135613d6581613b9d565b91506040840135613d7581613b9d565b809150509250925092565b8015158114612ee5575f80fd5b5f805f805f8060a08789031215613da2575f80fd5b863595506020870135613db481613d80565b94506040870135613dc481613b9d565b93506060870135613dd481613b9d565b9250608087013567ffffffffffffffff811115613def575f80fd5b613dfb89828a01613bcc565b979a9699509497509295939492505050565b5f8060408385031215613e1e575f80fd5b50508035926020909101359150565b803563ffffffff81168114613e40575f80fd5b919050565b5f805f8060808587031215613e58575f80fd5b8435613e6381613b9d565b935060208501356001600160e01b0381168114613e7e575f80fd5b9250613e8c60408601613e2d565b9150613e9a60608601613e2d565b905092959194509250565b602080825282518282018190525f9190848201906040850190845b81811015613ee55783516001600160a01b031683529284019291840191600101613ec0565b50909695505050505050565b5f8060408385031215613f02575f80fd5b8235613f0d81613b9d565b946020939093013593505050565b5f8060408385031215613f2c575f80fd5b8235613f3781613b9d565b91506020830135613cf781613b9d565b5f8060408385031215613f58575f80fd5b8235613f6381613b9d565b91506020830135613cf781613d80565b5f60208284031215613f83575f80fd5b815161243a81613d80565b5f60208284031215613f9e575f80fd5b815161243a81613b9d565b634e487b7160e01b5f52601160045260245ffd5b5f81613fcb57613fcb613fa9565b505f190190565b5f60208284031215613fe2575f80fd5b5051919050565b80820180821115610d8357610d83613fa9565b634e487b7160e01b5f52604160045260245ffd5b6040805190810167ffffffffffffffff8111828210171561403357614033613ffc565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561406257614062613ffc565b604052919050565b5f805f805f805f805f6101208a8c031215614083575f80fd5b61408d8a35613b9d565b8935985061409e60208b0135613b9d565b60208a013597506140b260408b0135613b9d565b60408a013596506140c660608b0135613b9d565b60608a013595506140da60808b0135613b9d565b60808a013594506140ee60a08b0135613b9d565b60a08a0135935061410260c08b0135613b9d565b60c08a0135925060e08a0135915067ffffffffffffffff6101008b01351115614129575f80fd5b8a601f6101008c01358c01011261413e575f80fd5b67ffffffffffffffff6101008b01358b0135111561415e5761415e613ffc565b61417560206101008c01358c013560051b01614039565b6101008b01358b0180358083526020808401939260069290921b909101018d101561419e575f80fd5b60206101008d01358d01015b6101008d01358d01803560061b01602001811015614204576040818f0312156141d1575f80fd5b6141d9614010565b813581526141ea6020830135613b9d565b6020828101358282015290845292909201916040016141aa565b5080925050509295985092959850929598565b634e487b7160e01b5f52603260045260245ffd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b602081525f61135f60208301848661422b565b83815260018060a01b0383166020820152606060408201525f82518060608401528060208501608085015e5f608082850101526080601f19601f830116840101915050949350505050565b6001600160a01b038581168252841660208201526060604082018190525f906142dd908301848661422b565b9695505050505050565b81810381811115610d8357610d83613fa9565b5f600160ff1b820161430e5761430e613fa9565b505f0390565b5f82518060208501845e5f920191825250919050565b634e487b7160e01b5f52603160045260245ffdfe627f9e4ac2dadb64d045e7e6333c09f39ed34e0e066957955d0052b46d2e83e8c1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e8237170593200002dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a2646970667358221220a4abd3b773c3b2209af423d73616a077f3c6a84e29bd5fc241febf1346ddba7b64736f6c6343000819003300000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000bb92a7b9695750e1234bab18f83b73686dd09854000000000000000000000000fe76b5fd238553d65ce6dd0a572c0fda629f842100000000000000000000000075fe0d73d3c64cdc1c6449d9f977be6857c4d01100000000000000000000000004b30b1e98950e6a13550d84e991be0d734c2c6100000000000000000000000000000000000000000000000000000000000000064d656c6c6f770000000000000000000000000000000000000000000000000000","name":"Vault","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":"src/libraries/TransferLibrary.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"@openzeppelin/contracts/utils/Address.sol\";\n\n/// @title TransferLibrary\n/// @notice Library for unified handling of native ETH and ERC20 asset transfers.\n/// @dev Provides safe and abstracted methods for sending and receiving both ETH and ERC20 tokens.\n///\n/// # ETH Convention\n/// Uses the constant `ETH = 0xEeee...EeE` to distinguish native ETH from ERC20 tokens.\nlibrary TransferLibrary {\n    using SafeERC20 for IERC20;\n\n    /// @notice Error thrown when `msg.value` does not match expected ETH amount\n    error InvalidValue();\n\n    /// @dev Placeholder address used to represent native ETH transfers\n    address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n\n    /// @notice Safely sends assets (ETH or ERC20) to a recipient\n    /// @param asset Address of the asset to send (use `ETH` constant for native ETH)\n    /// @param to Recipient address\n    /// @param assets Amount of assets to send\n    /// @dev Uses `Address.sendValue` for ETH and `safeTransfer` for ERC20\n    function sendAssets(address asset, address to, uint256 assets) internal {\n        if (asset == ETH) {\n            Address.sendValue(payable(to), assets);\n        } else {\n            IERC20(asset).safeTransfer(to, assets);\n        }\n    }\n\n    /// @notice Safely receives assets (ETH or ERC20) from a sender\n    /// @param asset Address of the asset to receive (use `ETH` constant for native ETH)\n    /// @param from Sender address (only used for ERC20)\n    /// @param assets Amount of assets expected to receive\n    /// @dev Reverts if `msg.value` is incorrect for ETH or uses `safeTransferFrom` for ERC20\n    function receiveAssets(address asset, address from, uint256 assets) internal {\n        if (asset == ETH) {\n            if (msg.value != assets) {\n                revert InvalidValue();\n            }\n        } else {\n            IERC20(asset).safeTransferFrom(from, address(this), assets);\n        }\n    }\n\n    /// @notice Returns the balance of an account for a given asset\n    /// @param asset Address of the asset to check the balance of (use `ETH` constant for native ETH)\n    /// @param account Address of the account to check the balance of\n    /// @return Balance of the account for the given asset\n    function balanceOf(address asset, address account) internal view returns (uint256) {\n        if (asset == ETH) {\n            return account.balance;\n        } else {\n            return IERC20(asset).balanceOf(account);\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/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC-20 standard as defined in the ERC.\n */\ninterface IERC20 {\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n    /**\n     * @dev Returns the value of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the value of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the\n     * allowance mechanism. `value` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address from, address to, uint256 value) external returns (bool);\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/modules/BaseModule.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../interfaces/modules/IBaseModule.sol\";\n\nabstract contract BaseModule is IBaseModule, ContextUpgradeable, ReentrancyGuardUpgradeable {\n    constructor() {\n        _disableInitializers();\n    }\n\n    // View functions\n\n    /// @inheritdoc IBaseModule\n    function getStorageAt(bytes32 slot) external pure returns (StorageSlot.Bytes32Slot memory) {\n        return StorageSlot.getBytes32Slot(slot);\n    }\n\n    /// @inheritdoc IERC721Receiver\n    function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) {\n        return IERC721Receiver.onERC721Received.selector;\n    }\n\n    // Mutable functions\n\n    receive() external payable {}\n\n    // Internal functions\n\n    function __BaseModule_init() internal onlyInitializing {\n        __ReentrancyGuard_init();\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":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../token/ERC20/IERC20.sol\";\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":"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/interfaces/IERC1363.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"./IERC20.sol\";\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @title IERC1363\n * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].\n *\n * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract\n * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.\n */\ninterface IERC1363 is IERC20, IERC165 {\n    /*\n     * Note: the ERC-165 identifier for this interface is 0xb0202a11.\n     * 0xb0202a11 ===\n     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^\n     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^\n     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))\n     */\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from the caller's account to `to`\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);\n\n    /**\n     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism\n     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.\n     * @param from The address which you want to send tokens from.\n     * @param to The address which you want to transfer to.\n     * @param value The amount of tokens to be transferred.\n     * @param data Additional data with no specified format, sent in call to `to`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value) external returns (bool);\n\n    /**\n     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.\n     * @param spender The address which will spend the funds.\n     * @param value The amount of tokens to be spent.\n     * @param data Additional data with no specified format, sent in call to `spender`.\n     * @return A boolean value indicating whether the operation succeeded unless throwing.\n     */\n    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);\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/interfaces/IERC165.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"../utils/introspection/IERC165.sol\";\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/token/ERC20/utils/SafeERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC20} from \"../IERC20.sol\";\nimport {IERC1363} from \"../../../interfaces/IERC1363.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC-20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    /**\n     * @dev An operation with an ERC-20 token failed.\n     */\n    error SafeERC20FailedOperation(address token);\n\n    /**\n     * @dev Indicates a failed `decreaseAllowance` request.\n     */\n    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));\n    }\n\n    /**\n     * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {\n        return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));\n    }\n\n    /**\n     * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.\n     */\n    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {\n        return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        forceApprove(token, spender, oldAllowance + value);\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\n     * value, non-reverting calls are assumed to be successful.\n     *\n     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the \"client\"\n     * smart contract uses ERC-7674 to set temporary allowances, then the \"client\" smart contract should avoid using\n     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract\n     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\n        unchecked {\n            uint256 currentAllowance = token.allowance(address(this), spender);\n            if (currentAllowance < requestedDecrease) {\n                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\n            }\n            forceApprove(token, spender, currentAllowance - requestedDecrease);\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     *\n     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function\n     * only sets the \"standard\" allowance. Any temporary allowance will remain active, in addition to the value being\n     * set here.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            safeTransfer(token, to, value);\n        } else if (!token.transferAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target\n     * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function transferFromAndCallRelaxed(\n        IERC1363 token,\n        address from,\n        address to,\n        uint256 value,\n        bytes memory data\n    ) internal {\n        if (to.code.length == 0) {\n            safeTransferFrom(token, from, to, value);\n        } else if (!token.transferFromAndCall(from, to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no\n     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when\n     * targeting contracts.\n     *\n     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.\n     * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}\n     * once without retrying, and relies on the returned value to be true.\n     *\n     * Reverts if the returned value is other than `true`.\n     */\n    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {\n        if (to.code.length == 0) {\n            forceApprove(token, to, value);\n        } else if (!token.approveAndCall(to, value, data)) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            // bubble errors\n            if iszero(success) {\n                let ptr := mload(0x40)\n                returndatacopy(ptr, 0, returndatasize())\n                revert(ptr, returndatasize())\n            }\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n\n        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {\n            revert SafeERC20FailedOperation(address(token));\n        }\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        bool success;\n        uint256 returnSize;\n        uint256 returnValue;\n        assembly (\"memory-safe\") {\n            success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)\n            returnSize := returndatasize()\n            returnValue := mload(0)\n        }\n        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);\n    }\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":"src/permissions/MellowACL.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../interfaces/permissions/IMellowACL.sol\";\n\nimport \"../libraries/SlotLibrary.sol\";\n\nabstract contract MellowACL is IMellowACL, AccessControlEnumerableUpgradeable {\n    using EnumerableSet for EnumerableSet.Bytes32Set;\n\n    bytes32 private immutable _mellowACLStorageSlot;\n\n    constructor(string memory name_, uint256 version_) {\n        _mellowACLStorageSlot = SlotLibrary.getSlot(\"MellowACL\", name_, version_);\n        _disableInitializers();\n    }\n\n    // View functions\n\n    /// @inheritdoc IMellowACL\n    function supportedRoles() external view returns (uint256) {\n        return _mellowACLStorage().supportedRoles.length();\n    }\n\n    /// @inheritdoc IMellowACL\n    function supportedRoleAt(uint256 index) external view returns (bytes32) {\n        return _mellowACLStorage().supportedRoles.at(index);\n    }\n\n    /// @inheritdoc IMellowACL\n    function hasSupportedRole(bytes32 role) external view returns (bool) {\n        return _mellowACLStorage().supportedRoles.contains(role);\n    }\n\n    // Internal functions\n\n    function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {\n        if (super._grantRole(role, account)) {\n            if (_mellowACLStorage().supportedRoles.add(role)) {\n                emit RoleAdded(role);\n            }\n            return true;\n        }\n        return false;\n    }\n\n    function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {\n        if (super._revokeRole(role, account)) {\n            if (getRoleMemberCount(role) == 0) {\n                _mellowACLStorage().supportedRoles.remove(role);\n                emit RoleRemoved(role);\n            }\n            return true;\n        }\n        return false;\n    }\n\n    function _mellowACLStorage() private view returns (MellowACLStorage storage $) {\n        bytes32 slot = _mellowACLStorageSlot;\n        assembly {\n            $.slot := slot\n        }\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/modules/ACLModule.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../interfaces/modules/IACLModule.sol\";\n\nimport \"../libraries/SlotLibrary.sol\";\n\nimport \"../permissions/MellowACL.sol\";\nimport \"./BaseModule.sol\";\n\nabstract contract ACLModule is IACLModule, BaseModule, MellowACL {\n    constructor(string memory name_, uint256 version_) MellowACL(name_, version_) {}\n\n    // Internal functions\n\n    function __ACLModule_init(address admin_) internal onlyInitializing {\n        if (admin_ == address(0)) {\n            revert ZeroAddress();\n        }\n        _grantRole(DEFAULT_ADMIN_ROLE, admin_);\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/modules/ShareModule.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../interfaces/modules/IShareModule.sol\";\n\nimport \"../libraries/SlotLibrary.sol\";\nimport \"../libraries/TransferLibrary.sol\";\n\nimport \"./ACLModule.sol\";\n\nabstract contract ShareModule is IShareModule, ACLModule {\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    /// @inheritdoc IShareModule\n    bytes32 public constant SET_HOOK_ROLE = keccak256(\"modules.ShareModule.SET_HOOK_ROLE\");\n    /// @inheritdoc IShareModule\n    bytes32 public constant CREATE_QUEUE_ROLE = keccak256(\"modules.ShareModule.CREATE_QUEUE_ROLE\");\n    /// @inheritdoc IShareModule\n    bytes32 public constant SET_QUEUE_STATUS_ROLE = keccak256(\"modules.ShareModule.SET_QUEUE_STATUS_ROLE\");\n    /// @inheritdoc IShareModule\n    bytes32 public constant SET_QUEUE_LIMIT_ROLE = keccak256(\"modules.ShareModule.SET_QUEUE_LIMIT_ROLE\");\n    /// @inheritdoc IShareModule\n    bytes32 public constant REMOVE_QUEUE_ROLE = keccak256(\"modules.ShareModule.REMOVE_QUEUE_ROLE\");\n\n    /// @inheritdoc IShareModule\n    IFactory public immutable depositQueueFactory;\n    /// @inheritdoc IShareModule\n    IFactory public immutable redeemQueueFactory;\n\n    bytes32 private immutable _shareModuleStorageSlot;\n\n    constructor(string memory name_, uint256 version_, address depositQueueFactory_, address redeemQueueFactory_) {\n        _shareModuleStorageSlot = SlotLibrary.getSlot(\"ShareModule\", name_, version_);\n        depositQueueFactory = IFactory(depositQueueFactory_);\n        redeemQueueFactory = IFactory(redeemQueueFactory_);\n    }\n\n    // View functions\n\n    /// @inheritdoc IShareModule\n    function shareManager() public view returns (IShareManager) {\n        return IShareManager(_shareModuleStorage().shareManager);\n    }\n\n    /// @inheritdoc IShareModule\n    function feeManager() public view returns (IFeeManager) {\n        return IFeeManager(_shareModuleStorage().feeManager);\n    }\n\n    /// @inheritdoc IShareModule\n    function oracle() public view returns (IOracle) {\n        return IOracle(_shareModuleStorage().oracle);\n    }\n\n    /// @inheritdoc IShareModule\n    function hasQueue(address queue) public view returns (bool) {\n        return _shareModuleStorage().queues[IQueue(queue).asset()].contains(queue);\n    }\n\n    /// @inheritdoc IShareModule\n    function getAssetCount() public view returns (uint256) {\n        return _shareModuleStorage().assets.length();\n    }\n\n    /// @inheritdoc IShareModule\n    function assetAt(uint256 index) public view returns (address) {\n        return _shareModuleStorage().assets.at(index);\n    }\n\n    /// @inheritdoc IShareModule\n    function hasAsset(address asset) public view returns (bool) {\n        return _shareModuleStorage().assets.contains(asset);\n    }\n\n    /// @inheritdoc IShareModule\n    function queueAt(address asset, uint256 index) public view returns (address) {\n        return _shareModuleStorage().queues[asset].at(index);\n    }\n\n    /// @inheritdoc IShareModule\n    function getQueueCount() public view returns (uint256) {\n        return _shareModuleStorage().queueCount;\n    }\n\n    /// @inheritdoc IShareModule\n    function getQueueCount(address asset) public view returns (uint256) {\n        return _shareModuleStorage().queues[asset].length();\n    }\n\n    /// @inheritdoc IShareModule\n    function queueLimit() public view returns (uint256) {\n        return _shareModuleStorage().queueLimit;\n    }\n\n    /// @inheritdoc IShareModule\n    function isDepositQueue(address queue) public view returns (bool) {\n        return _shareModuleStorage().isDepositQueue[queue];\n    }\n\n    /// @inheritdoc IShareModule\n    function isPausedQueue(address queue) public view returns (bool) {\n        return _shareModuleStorage().isPausedQueue[queue];\n    }\n\n    /// @inheritdoc IShareModule\n    function defaultDepositHook() public view returns (address) {\n        return _shareModuleStorage().defaultDepositHook;\n    }\n\n    /// @inheritdoc IShareModule\n    function defaultRedeemHook() public view returns (address) {\n        return _shareModuleStorage().defaultRedeemHook;\n    }\n\n    /// @inheritdoc IShareModule\n    function claimableSharesOf(address account) public view returns (uint256 shares) {\n        ShareModuleStorage storage $ = _shareModuleStorage();\n        EnumerableSet.AddressSet storage assets = $.assets;\n        uint256 assetsCount = assets.length();\n        for (uint256 i = 0; i < assetsCount; i++) {\n            address asset = assets.at(i);\n            EnumerableSet.AddressSet storage queues = $.queues[asset];\n            uint256 queuesCount = queues.length();\n            for (uint256 j = 0; j < queuesCount; j++) {\n                address queue = queues.at(j);\n                if ($.isDepositQueue[queue]) {\n                    shares += IDepositQueue(queue).claimableOf(account);\n                }\n            }\n        }\n        return shares;\n    }\n\n    /// @inheritdoc IShareModule\n    function getHook(address queue) public view returns (address) {\n        ShareModuleStorage storage $ = _shareModuleStorage();\n        address hook = $.customHooks[queue];\n        return hook != address(0) ? hook : $.isDepositQueue[queue] ? $.defaultDepositHook : $.defaultRedeemHook;\n    }\n\n    /// @inheritdoc IShareModule\n    function getLiquidAssets() public view returns (uint256) {\n        address queue = _msgSender();\n        address asset = IQueue(queue).asset();\n        ShareModuleStorage storage $ = _shareModuleStorage();\n        if (!$.queues[asset].contains(queue) || $.isDepositQueue[queue]) {\n            revert Forbidden();\n        }\n        address hook = getHook(queue);\n        if (hook == address(0)) {\n            return TransferLibrary.balanceOf(asset, address(this));\n        }\n        return IRedeemHook(hook).getLiquidAssets(asset);\n    }\n\n    // Mutable functions\n\n    /// @inheritdoc IShareModule\n    function setCustomHook(address queue, address hook) external onlyRole(SET_HOOK_ROLE) {\n        if (queue == address(0)) {\n            revert ZeroAddress();\n        }\n        _shareModuleStorage().customHooks[queue] = hook;\n        emit CustomHookSet(queue, hook);\n    }\n\n    /// @inheritdoc IShareModule\n    function setDefaultDepositHook(address hook) external onlyRole(SET_HOOK_ROLE) {\n        _shareModuleStorage().defaultDepositHook = hook;\n        emit DefaultHookSet(hook, true);\n    }\n\n    /// @inheritdoc IShareModule\n    function setDefaultRedeemHook(address hook) external onlyRole(SET_HOOK_ROLE) {\n        _shareModuleStorage().defaultRedeemHook = hook;\n        emit DefaultHookSet(hook, false);\n    }\n\n    /// @inheritdoc IShareModule\n    function setQueueLimit(uint256 limit) external onlyRole(SET_QUEUE_LIMIT_ROLE) {\n        _shareModuleStorage().queueLimit = limit;\n        emit QueueLimitSet(limit);\n    }\n\n    /// @inheritdoc IShareModule\n    function setQueueStatus(address queue, bool isPaused) external onlyRole(SET_QUEUE_STATUS_ROLE) {\n        if (!hasQueue(queue)) {\n            revert Forbidden();\n        }\n        _shareModuleStorage().isPausedQueue[queue] = isPaused;\n        emit SetQueueStatus(queue, isPaused);\n    }\n\n    /// @inheritdoc IShareModule\n    function createQueue(uint256 version, bool isDeposit, address owner, address asset, bytes calldata data)\n        external\n        nonReentrant\n        onlyRole(CREATE_QUEUE_ROLE)\n    {\n        ShareModuleStorage storage $ = _shareModuleStorage();\n        if (!IOracle($.oracle).isSupportedAsset(asset)) {\n            revert UnsupportedAsset(asset);\n        }\n        uint256 count = $.queueCount + 1;\n        if (count > $.queueLimit) {\n            revert QueueLimitReached();\n        }\n        address queue = (isDeposit ? depositQueueFactory : redeemQueueFactory).create(\n            version, owner, abi.encode(asset, address(this), data)\n        );\n        $.queueCount = count;\n        $.queues[asset].add(queue);\n        $.assets.add(asset);\n        $.isDepositQueue[queue] = isDeposit;\n        emit QueueCreated(queue, asset, isDeposit);\n    }\n\n    /// @inheritdoc IShareModule\n    function removeQueue(address queue) external onlyRole(REMOVE_QUEUE_ROLE) {\n        if (!IQueue(queue).canBeRemoved()) {\n            revert Forbidden();\n        }\n        address asset = IQueue(queue).asset();\n        ShareModuleStorage storage $ = _shareModuleStorage();\n        if (!$.queues[asset].remove(queue)) {\n            revert Forbidden();\n        }\n        delete $.isDepositQueue[queue];\n        if ($.queues[asset].length() == 0) {\n            $.assets.remove(asset);\n        }\n        delete $.customHooks[queue];\n        --$.queueCount;\n        emit QueueRemoved(queue, asset);\n    }\n\n    /// @inheritdoc IShareModule\n    function claimShares(address account) external {\n        ShareModuleStorage storage $ = _shareModuleStorage();\n        EnumerableSet.AddressSet storage assets = $.assets;\n        uint256 assetsCount = assets.length();\n        for (uint256 i = 0; i < assetsCount; i++) {\n            address asset = assets.at(i);\n            EnumerableSet.AddressSet storage queues = $.queues[asset];\n            uint256 queuesCount = queues.length();\n            for (uint256 j = 0; j < queuesCount; j++) {\n                address queue = queues.at(j);\n                if ($.isDepositQueue[queue]) {\n                    IDepositQueue(queue).claim(account);\n                }\n            }\n        }\n        emit SharesClaimed(account);\n    }\n\n    /// @inheritdoc IShareModule\n    function callHook(uint256 assets) external {\n        address queue = _msgSender();\n        address asset = IQueue(queue).asset();\n        ShareModuleStorage storage $ = _shareModuleStorage();\n        if (!_shareModuleStorage().queues[asset].contains(queue)) {\n            revert Forbidden();\n        }\n        address hook = getHook(queue);\n        if (hook != address(0)) {\n            Address.functionDelegateCall(hook, abi.encodeCall(IHook.callHook, (asset, assets)));\n        }\n        if (!$.isDepositQueue[queue]) {\n            TransferLibrary.sendAssets(asset, queue, assets);\n        }\n        emit HookCalled(queue, asset, assets, hook);\n    }\n\n    /// @inheritdoc IShareModule\n    function handleReport(address asset, uint224 priceD18, uint32 depositTimestamp, uint32 redeemTimestamp)\n        external\n        nonReentrant\n    {\n        ShareModuleStorage storage $ = _shareModuleStorage();\n        if (_msgSender() != $.oracle) {\n            revert Forbidden();\n        }\n        IShareManager shareManager_ = IShareManager($.shareManager);\n        IFeeManager feeManager_ = IFeeManager($.feeManager);\n        uint256 fees;\n        if (asset == feeManager_.baseAsset(address(this))) {\n            address feeRecipient_ = feeManager_.feeRecipient();\n            fees = feeManager_.calculateFee(\n                address(this),\n                asset,\n                priceD18,\n                shareManager_.totalShares() - shareManager_.activeSharesOf(feeRecipient_)\n            );\n            if (fees != 0) {\n                shareManager_.mint(feeRecipient_, fees);\n            }\n            feeManager_.updateState(asset, priceD18);\n        }\n        EnumerableSet.AddressSet storage queues = _shareModuleStorage().queues[asset];\n        uint256 length = queues.length();\n        for (uint256 i = 0; i < length; i++) {\n            address queue = queues.at(i);\n            IQueue(queue).handleReport(priceD18, $.isDepositQueue[queue] ? depositTimestamp : redeemTimestamp);\n        }\n        emit ReportHandled(asset, priceD18, depositTimestamp, redeemTimestamp, fees);\n    }\n\n    // Internal functions\n\n    function __ShareModule_init(\n        address shareManager_,\n        address feeManager_,\n        address oracle_,\n        address defaultDepositHook_,\n        address defaultRedeemHook_,\n        uint256 queueLimit_\n    ) internal onlyInitializing {\n        if (shareManager_ == address(0) || feeManager_ == address(0) || oracle_ == address(0)) {\n            revert ZeroAddress();\n        }\n        ShareModuleStorage storage $ = _shareModuleStorage();\n        $.shareManager = shareManager_;\n        $.feeManager = feeManager_;\n        $.oracle = oracle_;\n        $.defaultDepositHook = defaultDepositHook_;\n        $.defaultRedeemHook = defaultRedeemHook_;\n        $.queueLimit = queueLimit_;\n    }\n\n    function _shareModuleStorage() internal view returns (ShareModuleStorage storage $) {\n        bytes32 slot = _shareModuleStorageSlot;\n        assembly {\n            $.slot := slot\n        }\n    }\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":"src/modules/VaultModule.sol","source_code":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.25;\n\nimport \"../interfaces/modules/IVaultModule.sol\";\n\nimport \"../libraries/SlotLibrary.sol\";\nimport \"../libraries/TransferLibrary.sol\";\n\nimport \"./ACLModule.sol\";\n\nabstract contract VaultModule is IVaultModule, ACLModule {\n    using EnumerableSet for EnumerableSet.AddressSet;\n\n    /// @inheritdoc IVaultModule\n    bytes32 public constant CREATE_SUBVAULT_ROLE = keccak256(\"modules.VaultModule.CREATE_SUBVAULT_ROLE\");\n    /// @inheritdoc IVaultModule\n    bytes32 public constant DISCONNECT_SUBVAULT_ROLE = keccak256(\"modules.VaultModule.DISCONNECT_SUBVAULT_ROLE\");\n    /// @inheritdoc IVaultModule\n    bytes32 public constant RECONNECT_SUBVAULT_ROLE = keccak256(\"modules.VaultModule.RECONNECT_SUBVAULT_ROLE\");\n    /// @inheritdoc IVaultModule\n    bytes32 public constant PULL_LIQUIDITY_ROLE = keccak256(\"modules.VaultModule.PULL_LIQUIDITY_ROLE\");\n    /// @inheritdoc IVaultModule\n    bytes32 public constant PUSH_LIQUIDITY_ROLE = keccak256(\"modules.VaultModule.PUSH_LIQUIDITY_ROLE\");\n\n    /// @inheritdoc IVaultModule\n    IFactory public immutable subvaultFactory;\n    /// @inheritdoc IVaultModule\n    IFactory public immutable verifierFactory;\n\n    bytes32 private immutable _subvaultModuleStorageSlot;\n\n    constructor(string memory name_, uint256 version_, address subvaultFactory_, address verifierFactory_) {\n        _subvaultModuleStorageSlot = SlotLibrary.getSlot(\"VaultModule\", name_, version_);\n        subvaultFactory = IFactory(subvaultFactory_);\n        verifierFactory = IFactory(verifierFactory_);\n    }\n\n    // View functionss\n\n    /// @inheritdoc IVaultModule\n    function subvaults() public view returns (uint256) {\n        return _vaultStorage().subvaults.length();\n    }\n\n    /// @inheritdoc IVaultModule\n    function subvaultAt(uint256 index) public view returns (address) {\n        return _vaultStorage().subvaults.at(index);\n    }\n\n    /// @inheritdoc IVaultModule\n    function hasSubvault(address subvault) public view returns (bool) {\n        return _vaultStorage().subvaults.contains(subvault);\n    }\n\n    /// @inheritdoc IVaultModule\n    function riskManager() public view returns (IRiskManager) {\n        return IRiskManager(_vaultStorage().riskManager);\n    }\n\n    // Mutable functions\n\n    /// @inheritdoc IVaultModule\n    function createSubvault(uint256 version, address owner, address verifier)\n        external\n        onlyRole(CREATE_SUBVAULT_ROLE)\n        nonReentrant\n        returns (address subvault)\n    {\n        if (!verifierFactory.isEntity(verifier)) {\n            revert NotEntity(verifier);\n        }\n        if (address(IVerifier(verifier).vault()) != address(this)) {\n            revert Forbidden();\n        }\n        subvault = subvaultFactory.create(version, owner, abi.encode(verifier, address(this)));\n        _vaultStorage().subvaults.add(subvault);\n        emit SubvaultCreated(subvault, version, owner, verifier);\n    }\n\n    /// @inheritdoc IVaultModule\n    function disconnectSubvault(address subvault) external onlyRole(DISCONNECT_SUBVAULT_ROLE) {\n        VaultModuleStorage storage $ = _vaultStorage();\n        if (!$.subvaults.remove(subvault)) {\n            revert NotConnected(subvault);\n        }\n        emit SubvaultDisconnected(subvault);\n    }\n\n    /// @inheritdoc IVaultModule\n    function reconnectSubvault(address subvault) external onlyRole(RECONNECT_SUBVAULT_ROLE) {\n        VaultModuleStorage storage $ = _vaultStorage();\n        if (!subvaultFactory.isEntity(subvault)) {\n            revert NotEntity(subvault);\n        }\n        if (ISubvaultModule(subvault).vault() != address(this)) {\n            revert InvalidSubvault(subvault);\n        }\n        IVerifier verifier = IVerifierModule(subvault).verifier();\n        if (!verifierFactory.isEntity(address(verifier))) {\n            revert NotEntity(address(verifier));\n        }\n        if (address(verifier.vault()) != address(this)) {\n            revert Forbidden();\n        }\n        if (!$.subvaults.add(subvault)) {\n            revert AlreadyConnected(subvault);\n        }\n        emit SubvaultReconnected(subvault, address(verifier));\n    }\n\n    /// @inheritdoc IVaultModule\n    function pullAssets(address subvault, address asset, uint256 value)\n        external\n        onlyRole(PULL_LIQUIDITY_ROLE)\n        nonReentrant\n    {\n        _pullAssets(subvault, asset, value);\n    }\n\n    /// @inheritdoc IVaultModule\n    function pushAssets(address subvault, address asset, uint256 value)\n        external\n        onlyRole(PUSH_LIQUIDITY_ROLE)\n        nonReentrant\n    {\n        _pushAssets(subvault, asset, value);\n    }\n\n    /// @inheritdoc IVaultModule\n    function hookPullAssets(address subvault, address asset, uint256 value) external {\n        if (_msgSender() != address(this)) {\n            revert Forbidden();\n        }\n        _pullAssets(subvault, asset, value);\n    }\n\n    /// @inheritdoc IVaultModule\n    function hookPushAssets(address subvault, address asset, uint256 value) external {\n        if (_msgSender() != address(this)) {\n            revert Forbidden();\n        }\n        _pushAssets(subvault, asset, value);\n    }\n\n    // Internal functions\n\n    function _pullAssets(address subvault, address asset, uint256 value) internal {\n        riskManager().modifySubvaultBalance(subvault, asset, -int256(value));\n        ISubvaultModule(subvault).pullAssets(asset, value);\n        emit AssetsPulled(asset, subvault, value);\n    }\n\n    function _pushAssets(address subvault, address asset, uint256 value) internal {\n        riskManager().modifySubvaultBalance(subvault, asset, int256(value));\n        TransferLibrary.sendAssets(asset, subvault, value);\n        emit AssetsPushed(asset, subvault, value);\n    }\n\n    function __VaultModule_init(address riskManager_) internal onlyInitializing {\n        if (riskManager_ == address(0)) {\n            revert ZeroAddress();\n        }\n        _vaultStorage().riskManager = riskManager_;\n    }\n\n    function _vaultStorage() private view returns (VaultModuleStorage storage $) {\n        bytes32 slot = _subvaultModuleStorageSlot;\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"},{"internalType":"address","name":"depositQueueFactory_","type":"address"},{"internalType":"address","name":"redeemQueueFactory_","type":"address"},{"internalType":"address","name":"subvaultFactory_","type":"address"},{"internalType":"address","name":"verifierFactory_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"subvault","type":"address"}],"name":"AlreadyConnected","type":"error"},{"inputs":[],"name":"FailedCall","type":"error"},{"inputs":[],"name":"Forbidden","type":"error"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[{"internalType":"address","name":"subvault","type":"address"}],"name":"InvalidSubvault","type":"error"},{"inputs":[{"internalType":"address","name":"subvault","type":"address"}],"name":"NotConnected","type":"error"},{"inputs":[{"internalType":"address","name":"subvault","type":"address"}],"name":"NotEntity","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"QueueLimitReached","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"UnsupportedAsset","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroValue","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"subvault","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"AssetsPulled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"subvault","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"AssetsPushed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"queue","type":"address"},{"indexed":true,"internalType":"address","name":"hook","type":"address"}],"name":"CustomHookSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"hook","type":"address"},{"indexed":false,"internalType":"bool","name":"isDepositHook","type":"bool"}],"name":"DefaultHookSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"queue","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"assets","type":"uint256"},{"indexed":false,"internalType":"address","name":"hook","type":"address"}],"name":"HookCalled","type":"event"},{"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":"queue","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"bool","name":"isDepositQueue","type":"bool"}],"name":"QueueCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"QueueLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"queue","type":"address"},{"indexed":true,"internalType":"address","name":"asset","type":"address"}],"name":"QueueRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"uint224","name":"priceD18","type":"uint224"},{"indexed":false,"internalType":"uint32","name":"depositTimestamp","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"redeemTimestamp","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"fees","type":"uint256"}],"name":"ReportHandled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"RoleAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"RoleRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"queue","type":"address"},{"indexed":true,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"SetQueueStatus","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"SharesClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"subvault","type":"address"},{"indexed":false,"internalType":"uint256","name":"version","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"verifier","type":"address"}],"name":"SubvaultCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"subvault","type":"address"}],"name":"SubvaultDisconnected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"subvault","type":"address"},{"indexed":true,"internalType":"address","name":"verifier","type":"address"}],"name":"SubvaultReconnected","type":"event"},{"inputs":[],"name":"CREATE_QUEUE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CREATE_SUBVAULT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DISCONNECT_SUBVAULT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PULL_LIQUIDITY_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUSH_LIQUIDITY_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECONNECT_SUBVAULT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REMOVE_QUEUE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_HOOK_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_QUEUE_LIMIT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_QUEUE_STATUS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"assetAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assets","type":"uint256"}],"name":"callHook","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"claimShares","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"claimableSharesOf","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"version","type":"uint256"},{"internalType":"bool","name":"isDeposit","type":"bool"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"createQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"version","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"verifier","type":"address"}],"name":"createSubvault","outputs":[{"internalType":"address","name":"subvault","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultDepositHook","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultRedeemHook","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"depositQueueFactory","outputs":[{"internalType":"contract IFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"subvault","type":"address"}],"name":"disconnectSubvault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeManager","outputs":[{"internalType":"contract IFeeManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAssetCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"queue","type":"address"}],"name":"getHook","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLiquidAssets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQueueCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"getQueueCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMembers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"slot","type":"bytes32"}],"name":"getStorageAt","outputs":[{"components":[{"internalType":"bytes32","name":"value","type":"bytes32"}],"internalType":"struct StorageSlot.Bytes32Slot","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint224","name":"priceD18","type":"uint224"},{"internalType":"uint32","name":"depositTimestamp","type":"uint32"},{"internalType":"uint32","name":"redeemTimestamp","type":"uint32"}],"name":"handleReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"hasAsset","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"queue","type":"address"}],"name":"hasQueue","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"subvault","type":"address"}],"name":"hasSubvault","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"hasSupportedRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"subvault","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"hookPullAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"subvault","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"hookPushAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initParams","type":"bytes"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"queue","type":"address"}],"name":"isDepositQueue","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"queue","type":"address"}],"name":"isPausedQueue","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"subvault","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"pullAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"subvault","type":"address"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"pushAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"queueAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"queueLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"subvault","type":"address"}],"name":"reconnectSubvault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeemQueueFactory","outputs":[{"internalType":"contract IFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"queue","type":"address"}],"name":"removeQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"riskManager","outputs":[{"internalType":"contract IRiskManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"queue","type":"address"},{"internalType":"address","name":"hook","type":"address"}],"name":"setCustomHook","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"hook","type":"address"}],"name":"setDefaultDepositHook","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"hook","type":"address"}],"name":"setDefaultRedeemHook","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"setQueueLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"queue","type":"address"},{"internalType":"bool","name":"isPaused","type":"bool"}],"name":"setQueueStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shareManager","outputs":[{"internalType":"contract IShareManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"subvaultAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"subvaultFactory","outputs":[{"internalType":"contract IFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"subvaults","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"supportedRoleAt","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supportedRoles","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"verifierFactory","outputs":[{"internalType":"contract IFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":"0x00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000bb92a7b9695750e1234bab18f83b73686dd09854000000000000000000000000fe76b5fd238553d65ce6dd0a572c0fda629f842100000000000000000000000075fe0d73d3c64cdc1c6449d9f977be6857c4d01100000000000000000000000004b30b1e98950e6a13550d84e991be0d734c2c6100000000000000000000000000000000000000000000000000000000000000064d656c6c6f770000000000000000000000000000000000000000000000000000"}