{"file_path":"lib/vault-v2/src/periphery/blue-public-allocator/BluePublicAllocator.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\n// Copyright (c) 2026 Morpho Association\npragma solidity 0.8.28;\n\nimport {IVaultV2} from \"../../interfaces/IVaultV2.sol\";\nimport {IVaultV2Factory} from \"../../interfaces/IVaultV2Factory.sol\";\nimport {IBluePublicAllocator, VaultData} from \"./interfaces/IBluePublicAllocator.sol\";\nimport {MarketParams} from \"../../../lib/morpho-blue/src/interfaces/IMorpho.sol\";\nimport {WAD} from \"../../libraries/ConstantsLib.sol\";\nimport {MathLib} from \"../../libraries/MathLib.sol\";\nimport {SafeERC20Lib} from \"../../libraries/SafeERC20Lib.sol\";\n\n/// @dev To be usable, the BluePublicAllocator must be set as an allocator of the vault.\n/// @dev Meant to be used with VaultV2 vaults only.\n/// @dev Active adapters must be MorphoMarketV1AdapterV2 adapters, otherwise the public allocator's absolute cap system\n/// could break.\n/// @dev The vault's allocators can manage the public allocators' settings.\n/// @dev Each reallocate and allocateFromIdle call costs a proportional penalty, paid by the caller in the vault's\n/// asset. The penalty is set per vault by the allocators and is transferred directly to the vault (a donation, which\n/// increases the rate like forceDeallocate penalties).\n/// @dev The penalty parameter of reallocate and allocateFromIdle protects callers against penalty changes between\n/// signing and execution.\n/// @dev The vault's caps are still enforced on the allocation, so allocation calls reverts if it would exceed them.\n/// @dev The public allocator's caps are not checked on allocations from the vault (either by allocators or through\n/// deposits).\n/// @dev The BluePublicAllocator opens the door for anybody to manipulate relative caps through short-term deposits (but\n/// it requires capital).\n/// @dev reallocate and allocateFromIdle can be made to revert by anyone frontrunning them (not only allocators): an\n/// allocate reverts if the vault cap is filled first, a deallocate reverts if shares stop covering assets.\n/// @dev Reallocations (notably through this contract) can reduce the vault's \"direct\" liquidity by pulling assets from\n/// idle and from the liquidity market. It can also block deposit by reaching the liquidity market's caps.\ncontract BluePublicAllocator is IBluePublicAllocator {\n    /* IMMUTABLES */\n\n    address public immutable vaultV2Factory;\n\n    /* STORAGE */\n\n    mapping(address vault => mapping(bytes32 id => uint256)) public absoluteCap;\n    mapping(address vault => mapping(bytes32 id => bool)) public canPullFromMarket;\n    mapping(address vault => mapping(address adapter => bool)) public isActiveAdapter;\n    mapping(address vault => VaultData) public vaultData;\n\n    /* CONSTRUCTOR */\n\n    constructor(address _vaultV2Factory) {\n        vaultV2Factory = _vaultV2Factory;\n    }\n\n    /* MULTICALL */\n\n    /// @dev Useful for EOAs to batch allocator calls.\n    /// @dev Does not return anything, because accounts who would use the return data would be contracts, which can do\n    /// the multicall themselves.\n    function multicall(bytes[] calldata data) external {\n        for (uint256 i = 0; i < data.length; i++) {\n            (bool success, bytes memory returnData) = address(this).delegatecall(data[i]);\n            if (!success) {\n                assembly (\"memory-safe\") {\n                    revert(add(32, returnData), mload(returnData))\n                }\n            }\n        }\n    }\n\n    /* AUTHORIZED FUNCTIONS */\n\n    function setIsActiveAdapter(address vault, address adapter, bool newIsActiveAdapter) external {\n        require(IVaultV2Factory(vaultV2Factory).isVaultV2(vault), NotVaultV2());\n        require(IVaultV2(vault).isAllocator(msg.sender), Unauthorized());\n        isActiveAdapter[vault][adapter] = newIsActiveAdapter;\n        emit SetIsActiveAdapter(msg.sender, vault, adapter, newIsActiveAdapter);\n    }\n\n    function setAbsoluteCap(address vault, address adapter, MarketParams calldata marketParams, uint256 newAbsoluteCap)\n        external\n    {\n        require(IVaultV2Factory(vaultV2Factory).isVaultV2(vault), NotVaultV2());\n        bytes32 id = vaultBlueId(adapter, marketParams);\n        require(IVaultV2(vault).isAllocator(msg.sender), Unauthorized());\n        absoluteCap[vault][id] = newAbsoluteCap;\n        emit SetAbsoluteCap(msg.sender, vault, adapter, marketParams, newAbsoluteCap);\n    }\n\n    function setCanPullFromMarket(\n        address vault,\n        address adapter,\n        MarketParams calldata marketParams,\n        bool newCanPullFromMarket\n    ) external {\n        require(IVaultV2Factory(vaultV2Factory).isVaultV2(vault), NotVaultV2());\n        require(IVaultV2(vault).isAllocator(msg.sender), Unauthorized());\n        canPullFromMarket[vault][vaultBlueId(adapter, marketParams)] = newCanPullFromMarket;\n        emit SetCanPullFromMarket(msg.sender, vault, adapter, marketParams, newCanPullFromMarket);\n    }\n\n    function setCanPullFromIdle(address vault, bool newCanPullFromIdle) external {\n        require(IVaultV2Factory(vaultV2Factory).isVaultV2(vault), NotVaultV2());\n        require(IVaultV2(vault).isAllocator(msg.sender), Unauthorized());\n        vaultData[vault].canPullFromIdle = newCanPullFromIdle;\n        emit SetCanPullFromIdle(msg.sender, vault, newCanPullFromIdle);\n    }\n\n    function setPenalty(address vault, uint64 newPenalty) external {\n        require(IVaultV2Factory(vaultV2Factory).isVaultV2(vault), NotVaultV2());\n        require(IVaultV2(vault).isAllocator(msg.sender), Unauthorized());\n        require(newPenalty <= WAD, PenaltyTooHigh());\n        vaultData[vault].penalty = newPenalty;\n        emit SetPenalty(msg.sender, vault, newPenalty);\n    }\n\n    /* PUBLIC FUNCTION */\n\n    function reallocate(\n        address vault,\n        address deallocateAdapter,\n        MarketParams calldata deallocateMarketParams,\n        address allocateAdapter,\n        MarketParams calldata allocateMarketParams,\n        uint128 assets,\n        uint64 penalty\n    ) external {\n        require(vaultData[vault].penalty == penalty, IncorrectPenalty());\n        uint256 penaltyAssets = MathLib.mulDivUp(assets, penalty, WAD);\n        if (penaltyAssets > 0) {\n            SafeERC20Lib.safeTransferFrom(allocateMarketParams.loanToken, msg.sender, vault, penaltyAssets);\n        }\n        require(isActiveAdapter[vault][deallocateAdapter], InactiveAdapter());\n        require(isActiveAdapter[vault][allocateAdapter], InactiveAdapter());\n        bytes32 deallocateId = vaultBlueId(deallocateAdapter, deallocateMarketParams);\n        require(canPullFromMarket[vault][deallocateId], CannotPullFromMarket());\n        bytes32 allocateId = vaultBlueId(allocateAdapter, allocateMarketParams);\n        require(absoluteCap[vault][allocateId] > 0, ZeroAbsoluteCap());\n\n        IVaultV2(vault).deallocate(deallocateAdapter, abi.encode(deallocateMarketParams), assets);\n        IVaultV2(vault).allocate(allocateAdapter, abi.encode(allocateMarketParams), assets);\n\n        require(IVaultV2(vault).allocation(allocateId) <= absoluteCap[vault][allocateId], AbsoluteCapExceeded());\n\n        emit Reallocate(\n            msg.sender, vault, deallocateAdapter, deallocateId, allocateAdapter, allocateId, assets, penaltyAssets\n        );\n    }\n\n    function allocateFromIdle(\n        address vault,\n        address adapter,\n        MarketParams calldata marketParams,\n        uint128 assets,\n        uint64 penalty\n    ) external {\n        require(vaultData[vault].penalty == penalty, IncorrectPenalty());\n        uint256 penaltyAssets = MathLib.mulDivUp(assets, penalty, WAD);\n        if (penaltyAssets > 0) SafeERC20Lib.safeTransferFrom(marketParams.loanToken, msg.sender, vault, penaltyAssets);\n        require(isActiveAdapter[vault][adapter], InactiveAdapter());\n        require(vaultData[vault].canPullFromIdle, CannotPullFromIdle());\n        bytes32 allocateId = vaultBlueId(adapter, marketParams);\n        require(absoluteCap[vault][allocateId] > 0, ZeroAbsoluteCap());\n\n        IVaultV2(vault).allocate(adapter, abi.encode(marketParams), assets);\n\n        require(IVaultV2(vault).allocation(allocateId) <= absoluteCap[vault][allocateId], AbsoluteCapExceeded());\n\n        emit AllocateFromIdle(msg.sender, vault, adapter, allocateId, assets, penaltyAssets);\n    }\n\n    /// @dev Returns the market's per-market vault id, exactly as keyed by the MorphoMarketV1AdapterV2.\n    function vaultBlueId(address adapter, MarketParams calldata marketParams) internal pure returns (bytes32) {\n        return keccak256(abi.encode(\"this/marketParams\", adapter, marketParams));\n    }\n}\n","deployed_bytecode":"0x6080806040526004361015610012575f80fd5b5f905f3560e01c90816308f804d81461188e575080635e0deb541461165157806366faa839146115c057806369f1e26b1461154c57806377b0aab1146113385780637953b569146112ca5780638aeed1d11461107d5780638fdaa1a714610a9f5780639a8a67951461086a5780639a8b594414610628578063ac9650d814610511578063d72ff79a146104975763df31d688146100ad575f80fd5b34610494576101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610494576100e56118f7565b6100ed61191a565b9060a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc3601126103b75760e435916fffffffffffffffffffffffffffffffff83169182840361049257610104359267ffffffffffffffff84168094036103a85773ffffffffffffffffffffffffffffffffffffffff82169384875260036020528067ffffffffffffffff604089205460081c160361046a576101909082611c7d565b9182610433575b5083865260026020526040862073ffffffffffffffffffffffffffffffffffffffff84165f5260205260ff60405f2054161561040b57838652600360205260ff604087205416156103e3576101eb83611c02565b9484875286602052604087208688526020526040872054156103bb578690604051610218602082016119e4565b60a0815261022760c08261195e565b863b156103b75761026991839160405193849283927f5c9ce04d0000000000000000000000000000000000000000000000000000000084528a60048501611b24565b0381838a5af180156103ac57610393575b50506040517fc69507dd000000000000000000000000000000000000000000000000000000008152856004820152602081602481885afa908115610388578791610352575b50848752866020526040872086885260205260408720541061032a5773ffffffffffffffffffffffffffffffffffffffff60405193168352602083015260408201527f141dc311848af2dd1094d09b33fbf388787803a6f8d59038c066adf920300cff60603392a480f35b6004867f4616e4af000000000000000000000000000000000000000000000000000000008152fd5b90506020813d602011610380575b8161036d6020938361195e565b8101031261037c57515f6102bf565b5f80fd5b3d9150610360565b6040513d89823e3d90fd5b8161039d9161195e565b6103a857855f61027a565b8580fd5b6040513d84823e3d90fd5b8280fd5b6004877fbb1a23b9000000000000000000000000000000000000000000000000000000008152fd5b6004867f79211beb000000000000000000000000000000000000000000000000000000008152fd5b6004867f8d3a1180000000000000000000000000000000000000000000000000000000008152fd5b60443573ffffffffffffffffffffffffffffffffffffffff81168103610466576104609184913390611cda565b5f610197565b8780fd5b6004877f7267792a000000000000000000000000000000000000000000000000000000008152fd5b845b80fd5b50346104945760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610494576040809173ffffffffffffffffffffffffffffffffffffffff6104e86118f7565b1681526003602052205467ffffffffffffffff82519160ff81161515835260081c166020820152f35b50346104945760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610494576004359067ffffffffffffffff8211610494573660238301121561049457816004013567ffffffffffffffff8111610624573660248260051b85010111610624579181907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbd81360301915b848110156106205760248160051b830101358381121561049257820160248101359067ffffffffffffffff82116103a85760440181360381136103a857818692918392604051928392833781018381520390305af4610609611ba5565b901561061857506001016105ac565b805190602001fd5b8380f35b5080fd5b50346104945760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610494576106606118f7565b602435801515908181036108665773ffffffffffffffffffffffffffffffffffffffff604051937f5edec50d000000000000000000000000000000000000000000000000000000008552169283600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004501125508079a99ebbebce205dec9593c2b5857165afa908115610814578591610847575b501561081f576040517f4dedf20e000000000000000000000000000000000000000000000000000000008152336004820152602081602481875afa9081156108145785916107e5575b50156107bd5761078e908385526003602052604085209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b6040519081527f69f0f5f31610c9bb0b1c7325d8098a0c7d6093e0ea7fbf9920eb46f349bfe07c60203392a380f35b6004847f82b42900000000000000000000000000000000000000000000000000000000008152fd5b610807915060203d60201161080d575b6107ff818361195e565b8101906119cc565b5f610748565b503d6107f5565b6040513d87823e3d90fd5b6004847f1a9141e7000000000000000000000000000000000000000000000000000000008152fd5b610860915060203d60201161080d576107ff818361195e565b5f6106ff565b8380fd5b5034610494576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610494576108a36118f7565b6108ab61191a565b60a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc3601126103b75760e43573ffffffffffffffffffffffffffffffffffffffff604051937f5edec50d000000000000000000000000000000000000000000000000000000008552169283600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004501125508079a99ebbebce205dec9593c2b5857165afa908115610814578591610a80575b501561081f5761097882611c02565b6040517f4dedf20e000000000000000000000000000000000000000000000000000000008152336004820152602081602481885afa908115610a75578691610a56575b5015610a2e57838552846020526040852090855260205280604085205573ffffffffffffffffffffffffffffffffffffffff60405192168252610a00602083016119e4565b60c08201527f1a77abe8031078d6f3fc79dbd2a5cfa48ae8dbb495fcf0b3124cf009bb6d91c360e03392a380f35b6004857f82b42900000000000000000000000000000000000000000000000000000000008152fd5b610a6f915060203d60201161080d576107ff818361195e565b5f6109bb565b6040513d88823e3d90fd5b610a99915060203d60201161080d576107ff818361195e565b5f610969565b503461037c576101e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c57610ad86118f7565b610ae061191a565b9060a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc36011261037c5760e4359173ffffffffffffffffffffffffffffffffffffffff83169081840361037c5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefc36011261037c576101a435926fffffffffffffffffffffffffffffffff841680850361037c576101c4359367ffffffffffffffff851680950361037c5773ffffffffffffffffffffffffffffffffffffffff831694855f5260036020528067ffffffffffffffff60405f205460081c160361105557610bd09083611c7d565b9283611021575b50845f52600260205260405f2073ffffffffffffffffffffffffffffffffffffffff85165f5260205260ff60405f20541615610ff957845f52600260205260405f20815f5260205260ff60405f20541615610ff957610c3584611c02565b95855f52600160205260405f20875f5260205260ff60405f20541615610fd157604051602081019060e0825260116101008201527f746869732f6d61726b6574506172616d73000000000000000000000000000000610120820152836040820152610ca560608201610104611a83565b6101208152610cb66101408261195e565b51902097865f525f60205260405f20895f5260205260405f205415610fa957604051610ce4602082016119e4565b60a08152610cf360c08261195e565b873b1561037c575f83610d359260405193849283927f4b219d160000000000000000000000000000000000000000000000000000000084528c60048501611b24565b0381838c5af18015610f9e57610f87575b509089916040516101043573ffffffffffffffffffffffffffffffffffffffff81168091036104925760208201526101243573ffffffffffffffffffffffffffffffffffffffff81168091036104925760408201526101443573ffffffffffffffffffffffffffffffffffffffff81168091036104925760608201526101643573ffffffffffffffffffffffffffffffffffffffff81168091036104925760808201526101843560a082015260a08152610e0160c08261195e565b883b15610866578391610e4160405194859384937f5c9ce04d00000000000000000000000000000000000000000000000000000000855260048501611b24565b0381838b5af180156103ac57610f72575b50506040517fc69507dd000000000000000000000000000000000000000000000000000000008152876004820152602081602481895afa908115610f67578991610f35575b508589528860205260408920888a52602052604089205410610f0d576040805133815273ffffffffffffffffffffffffffffffffffffffff9095166020860152840152606083015260808201527f813a174ef9435466c79f45c3051c14bab72e0c8f5d0f265105e33c3d6d5ddcf79060a090a480f35b6004887f4616e4af000000000000000000000000000000000000000000000000000000008152fd5b90506020813d602011610f5f575b81610f506020938361195e565b8101031261037c57515f610e97565b3d9150610f43565b6040513d8b823e3d90fd5b81610f7c9161195e565b61046657875f610e52565b610f9591929a505f9061195e565b5f98905f610d46565b6040513d5f823e3d90fd5b7fbb1a23b9000000000000000000000000000000000000000000000000000000005f5260045ffd5b7fff07b0d3000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f8d3a1180000000000000000000000000000000000000000000000000000000005f5260045ffd5b6101043573ffffffffffffffffffffffffffffffffffffffff8116810361037c5761104f9185913390611cda565b5f610bd7565b7f7267792a000000000000000000000000000000000000000000000000000000005f5260045ffd5b3461037c5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c576110b46118f7565b6110bc61191a565b906044358015159283820361037c5773ffffffffffffffffffffffffffffffffffffffff604051937f5edec50d000000000000000000000000000000000000000000000000000000008552169283600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004501125508079a99ebbebce205dec9593c2b5857165afa908115610f9e575f916112ab575b5015611283576040517f4dedf20e000000000000000000000000000000000000000000000000000000008152336004820152602081602481875afa908115610f9e575f91611264575b501561123c5761120c73ffffffffffffffffffffffffffffffffffffffff92845f52600260205260405f208484165f5260205260405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b60405193845216917fcb0caee6dfd90d41657a1c2834c4139aff2ad434ddb51eecd2ea298d3580953e60203392a4005b7f82b42900000000000000000000000000000000000000000000000000000000005f5260045ffd5b61127d915060203d60201161080d576107ff818361195e565b856111a5565b7f1a9141e7000000000000000000000000000000000000000000000000000000005f5260045ffd5b6112c4915060203d60201161080d576107ff818361195e565b8561115c565b3461037c575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004501125508079a99ebbebce205dec9593c2b5857168152f35b3461037c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c5761136f6118f7565b60243567ffffffffffffffff81169081810361037c5773ffffffffffffffffffffffffffffffffffffffff604051937f5edec50d000000000000000000000000000000000000000000000000000000008552169283600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004501125508079a99ebbebce205dec9593c2b5857165afa908115610f9e575f9161152d575b5015611283576040517f4dedf20e000000000000000000000000000000000000000000000000000000008152336004820152602081602481875afa908115610f9e575f9161150e575b501561123c57670de0b6b3a764000082116114e657825f52600360205260405f20907fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff68ffffffffffffffff0083549260081b1691161790556040519081527f87592866e19f1c7e3aba38aff71910bf6cde4d2aea6dd48bacc5d21b59f68b8c60203392a3005b7f516e7f38000000000000000000000000000000000000000000000000000000005f5260045ffd5b611527915060203d60201161080d576107ff818361195e565b8461145f565b611546915060203d60201161080d576107ff818361195e565b84611416565b3461037c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c5773ffffffffffffffffffffffffffffffffffffffff6115986118f7565b165f52600160205260405f206024355f52602052602060ff60405f2054166040519015158152f35b3461037c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c576115f76118f7565b73ffffffffffffffffffffffffffffffffffffffff61161461191a565b91165f52600260205273ffffffffffffffffffffffffffffffffffffffff60405f2091165f52602052602060ff60405f2054166040519015158152f35b3461037c576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c576116896118f7565b61169161191a565b60a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc36011261037c5760e4358015159081810361037c5773ffffffffffffffffffffffffffffffffffffffff604051947f5edec50d000000000000000000000000000000000000000000000000000000008652169384600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004501125508079a99ebbebce205dec9593c2b5857165afa908115610f9e575f9161186f575b5015611283576040517f4dedf20e000000000000000000000000000000000000000000000000000000008152336004820152602081602481885afa908115610f9e575f91611850575b501561123c576117fb90845f52600160205260405f206117c285611c02565b5f5260205260405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b73ffffffffffffffffffffffffffffffffffffffff60405192168252611823602083016119e4565b60c08201527facfd800238adbc79248c080c459b374b06feb519a69654529b318273686e1ab660e03392a3005b611869915060203d60201161080d576107ff818361195e565b856117a3565b611888915060203d60201161080d576107ff818361195e565b8561175a565b3461037c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c5760209073ffffffffffffffffffffffffffffffffffffffff6118dd6118f7565b165f525f825260405f206024355f52825260405f20548152f35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361037c57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361037c57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361037c57565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761199f57604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b9081602091031261037c5751801515810361037c5790565b60443573ffffffffffffffffffffffffffffffffffffffff811680910361037c57815260643573ffffffffffffffffffffffffffffffffffffffff811680910361037c57602082015260843573ffffffffffffffffffffffffffffffffffffffff811680910361037c57604082015260a43573ffffffffffffffffffffffffffffffffffffffff811680910361037c576060820152608060c435910152565b6080809173ffffffffffffffffffffffffffffffffffffffff611aa58261193d565b16845273ffffffffffffffffffffffffffffffffffffffff611ac96020830161193d565b16602085015273ffffffffffffffffffffffffffffffffffffffff611af06040830161193d565b16604085015273ffffffffffffffffffffffffffffffffffffffff611b176060830161193d565b1660608501520135910152565b9160807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60206fffffffffffffffffffffffffffffffff9473ffffffffffffffffffffffffffffffffffffffff6040979a999a16885260608289015280519182918260608b0152018589015e5f84828901015201168401019416910152565b3d15611bfd573d9067ffffffffffffffff821161199f5760405191611bf260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116018461195e565b82523d5f602084013e565b606090565b60405173ffffffffffffffffffffffffffffffffffffffff602082019260e0845260116101008401527f746869732f6d61726b6574506172616d73000000000000000000000000000000610120840152166040820152611c66606082016044611a83565b6101208152611c776101408261195e565b51902090565b818102918183041490151715611cad57670de0b6b3a763ffff8101809111611cad57670de0b6b3a7640000900490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b90813b15611ddc575f809493819473ffffffffffffffffffffffffffffffffffffffff604051928160208501967f23b872dd000000000000000000000000000000000000000000000000000000008852166024850152166044830152606482015260648152611d4a60848261195e565b51925af1611d56611ba5565b9015611db4578051908115918215611d9a575b505015611d7257565b7f1eded19c000000000000000000000000000000000000000000000000000000005f5260045ffd5b611dad92506020809183010191016119cc565b5f80611d69565b7fe65b7a77000000000000000000000000000000000000000000000000000000005f5260045ffd5b7ff046a714000000000000000000000000000000000000000000000000000000005f5260045ffdfea164736f6c634300081c000a","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"cancun","libraries":{},"metadata":{"bytecodeHash":"none"},"optimizer":{"enabled":true,"runs":100000},"remappings":[":@openzeppelin/contracts/=lib/metamorpho-1.1/lib/openzeppelin-contracts/contracts/",":bundler3/=lib/bundler3/",":bundles/=lib/bundles/",":ds-test/=lib/metamorpho-1.1/lib/forge-std/lib/ds-test/src/",":erc4626-tests/=lib/metamorpho-1.1/lib/erc4626-tests/",":forge-gas-snapshot/=lib/bundler3/lib/permit2/lib/forge-gas-snapshot/src/",":forge-std/=lib/forge-std/src/",":halmos-cheatcodes/=lib/morpho-blue/lib/halmos-cheatcodes/src/",":metamorpho-1.1/=lib/metamorpho-1.1/",":metamorpho-v1.1/=lib/vault-v2/lib/metamorpho-v1.1/",":metamorpho/=lib/vault-v2/lib/metamorpho/",":midnight/=lib/midnight/",":morpho-blue-irm/=lib/morpho-blue-irm/src/",":morpho-blue-oracles/=lib/morpho-blue-oracles/src/",":morpho-blue/=lib/morpho-blue/",":murky/=lib/universal-rewards-distributor/lib/murky/src/",":openzeppelin-contracts/=lib/metamorpho-1.1/lib/openzeppelin-contracts/",":openzeppelin/=lib/universal-rewards-distributor/lib/openzeppelin-contracts/contracts/",":permit2/=lib/bundler3/lib/permit2/",":pre-liquidation/=lib/pre-liquidation/src/",":public-allocator/=lib/public-allocator/src/",":safe-smart-account/=lib/safe-smart-account/",":solmate/=lib/bundler3/lib/permit2/lib/solmate/",":universal-rewards-distributor/=lib/universal-rewards-distributor/src/",":vault-v2-adapter-registries/=lib/vault-v2-adapter-registries/src/",":vault-v2/=lib/vault-v2/"],"viaIR":true},"optimization_runs":100000,"sourcify_repo_url":"https://repo.sourcify.dev/contracts/partial_match/8453/0xAED282B8aD9257BB1272e93aE63A32A53621e412/","decoded_constructor_args":[["0x4501125508079A99ebBebCE205DeC9593C2b5857",{"internalType":"address","name":"_vaultV2Factory","type":"address"}]],"compiler_version":"0.8.28+commit.7893614a","is_verified_via_verifier_alliance":false,"verified_at":"2026-08-20T14:20:28.440690Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60a03461008d57601f611eb738819003918201601f19168301916001600160401b038311848410176100915780849260209460405283398101031261008d57516001600160a01b038116810361008d57608052604051611e1190816100a682396080518181816106cf015281816109390152818161112c01528181611314015281816113e6015261172a0152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f905f3560e01c90816308f804d81461188e575080635e0deb541461165157806366faa839146115c057806369f1e26b1461154c57806377b0aab1146113385780637953b569146112ca5780638aeed1d11461107d5780638fdaa1a714610a9f5780639a8a67951461086a5780639a8b594414610628578063ac9650d814610511578063d72ff79a146104975763df31d688146100ad575f80fd5b34610494576101207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610494576100e56118f7565b6100ed61191a565b9060a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc3601126103b75760e435916fffffffffffffffffffffffffffffffff83169182840361049257610104359267ffffffffffffffff84168094036103a85773ffffffffffffffffffffffffffffffffffffffff82169384875260036020528067ffffffffffffffff604089205460081c160361046a576101909082611c7d565b9182610433575b5083865260026020526040862073ffffffffffffffffffffffffffffffffffffffff84165f5260205260ff60405f2054161561040b57838652600360205260ff604087205416156103e3576101eb83611c02565b9484875286602052604087208688526020526040872054156103bb578690604051610218602082016119e4565b60a0815261022760c08261195e565b863b156103b75761026991839160405193849283927f5c9ce04d0000000000000000000000000000000000000000000000000000000084528a60048501611b24565b0381838a5af180156103ac57610393575b50506040517fc69507dd000000000000000000000000000000000000000000000000000000008152856004820152602081602481885afa908115610388578791610352575b50848752866020526040872086885260205260408720541061032a5773ffffffffffffffffffffffffffffffffffffffff60405193168352602083015260408201527f141dc311848af2dd1094d09b33fbf388787803a6f8d59038c066adf920300cff60603392a480f35b6004867f4616e4af000000000000000000000000000000000000000000000000000000008152fd5b90506020813d602011610380575b8161036d6020938361195e565b8101031261037c57515f6102bf565b5f80fd5b3d9150610360565b6040513d89823e3d90fd5b8161039d9161195e565b6103a857855f61027a565b8580fd5b6040513d84823e3d90fd5b8280fd5b6004877fbb1a23b9000000000000000000000000000000000000000000000000000000008152fd5b6004867f79211beb000000000000000000000000000000000000000000000000000000008152fd5b6004867f8d3a1180000000000000000000000000000000000000000000000000000000008152fd5b60443573ffffffffffffffffffffffffffffffffffffffff81168103610466576104609184913390611cda565b5f610197565b8780fd5b6004877f7267792a000000000000000000000000000000000000000000000000000000008152fd5b845b80fd5b50346104945760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610494576040809173ffffffffffffffffffffffffffffffffffffffff6104e86118f7565b1681526003602052205467ffffffffffffffff82519160ff81161515835260081c166020820152f35b50346104945760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610494576004359067ffffffffffffffff8211610494573660238301121561049457816004013567ffffffffffffffff8111610624573660248260051b85010111610624579181907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbd81360301915b848110156106205760248160051b830101358381121561049257820160248101359067ffffffffffffffff82116103a85760440181360381136103a857818692918392604051928392833781018381520390305af4610609611ba5565b901561061857506001016105ac565b805190602001fd5b8380f35b5080fd5b50346104945760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610494576106606118f7565b602435801515908181036108665773ffffffffffffffffffffffffffffffffffffffff604051937f5edec50d000000000000000000000000000000000000000000000000000000008552169283600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115610814578591610847575b501561081f576040517f4dedf20e000000000000000000000000000000000000000000000000000000008152336004820152602081602481875afa9081156108145785916107e5575b50156107bd5761078e908385526003602052604085209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b6040519081527f69f0f5f31610c9bb0b1c7325d8098a0c7d6093e0ea7fbf9920eb46f349bfe07c60203392a380f35b6004847f82b42900000000000000000000000000000000000000000000000000000000008152fd5b610807915060203d60201161080d575b6107ff818361195e565b8101906119cc565b5f610748565b503d6107f5565b6040513d87823e3d90fd5b6004847f1a9141e7000000000000000000000000000000000000000000000000000000008152fd5b610860915060203d60201161080d576107ff818361195e565b5f6106ff565b8380fd5b5034610494576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc360112610494576108a36118f7565b6108ab61191a565b60a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc3601126103b75760e43573ffffffffffffffffffffffffffffffffffffffff604051937f5edec50d000000000000000000000000000000000000000000000000000000008552169283600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115610814578591610a80575b501561081f5761097882611c02565b6040517f4dedf20e000000000000000000000000000000000000000000000000000000008152336004820152602081602481885afa908115610a75578691610a56575b5015610a2e57838552846020526040852090855260205280604085205573ffffffffffffffffffffffffffffffffffffffff60405192168252610a00602083016119e4565b60c08201527f1a77abe8031078d6f3fc79dbd2a5cfa48ae8dbb495fcf0b3124cf009bb6d91c360e03392a380f35b6004857f82b42900000000000000000000000000000000000000000000000000000000008152fd5b610a6f915060203d60201161080d576107ff818361195e565b5f6109bb565b6040513d88823e3d90fd5b610a99915060203d60201161080d576107ff818361195e565b5f610969565b503461037c576101e07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c57610ad86118f7565b610ae061191a565b9060a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc36011261037c5760e4359173ffffffffffffffffffffffffffffffffffffffff83169081840361037c5760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefc36011261037c576101a435926fffffffffffffffffffffffffffffffff841680850361037c576101c4359367ffffffffffffffff851680950361037c5773ffffffffffffffffffffffffffffffffffffffff831694855f5260036020528067ffffffffffffffff60405f205460081c160361105557610bd09083611c7d565b9283611021575b50845f52600260205260405f2073ffffffffffffffffffffffffffffffffffffffff85165f5260205260ff60405f20541615610ff957845f52600260205260405f20815f5260205260ff60405f20541615610ff957610c3584611c02565b95855f52600160205260405f20875f5260205260ff60405f20541615610fd157604051602081019060e0825260116101008201527f746869732f6d61726b6574506172616d73000000000000000000000000000000610120820152836040820152610ca560608201610104611a83565b6101208152610cb66101408261195e565b51902097865f525f60205260405f20895f5260205260405f205415610fa957604051610ce4602082016119e4565b60a08152610cf360c08261195e565b873b1561037c575f83610d359260405193849283927f4b219d160000000000000000000000000000000000000000000000000000000084528c60048501611b24565b0381838c5af18015610f9e57610f87575b509089916040516101043573ffffffffffffffffffffffffffffffffffffffff81168091036104925760208201526101243573ffffffffffffffffffffffffffffffffffffffff81168091036104925760408201526101443573ffffffffffffffffffffffffffffffffffffffff81168091036104925760608201526101643573ffffffffffffffffffffffffffffffffffffffff81168091036104925760808201526101843560a082015260a08152610e0160c08261195e565b883b15610866578391610e4160405194859384937f5c9ce04d00000000000000000000000000000000000000000000000000000000855260048501611b24565b0381838b5af180156103ac57610f72575b50506040517fc69507dd000000000000000000000000000000000000000000000000000000008152876004820152602081602481895afa908115610f67578991610f35575b508589528860205260408920888a52602052604089205410610f0d576040805133815273ffffffffffffffffffffffffffffffffffffffff9095166020860152840152606083015260808201527f813a174ef9435466c79f45c3051c14bab72e0c8f5d0f265105e33c3d6d5ddcf79060a090a480f35b6004887f4616e4af000000000000000000000000000000000000000000000000000000008152fd5b90506020813d602011610f5f575b81610f506020938361195e565b8101031261037c57515f610e97565b3d9150610f43565b6040513d8b823e3d90fd5b81610f7c9161195e565b61046657875f610e52565b610f9591929a505f9061195e565b5f98905f610d46565b6040513d5f823e3d90fd5b7fbb1a23b9000000000000000000000000000000000000000000000000000000005f5260045ffd5b7fff07b0d3000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f8d3a1180000000000000000000000000000000000000000000000000000000005f5260045ffd5b6101043573ffffffffffffffffffffffffffffffffffffffff8116810361037c5761104f9185913390611cda565b5f610bd7565b7f7267792a000000000000000000000000000000000000000000000000000000005f5260045ffd5b3461037c5760607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c576110b46118f7565b6110bc61191a565b906044358015159283820361037c5773ffffffffffffffffffffffffffffffffffffffff604051937f5edec50d000000000000000000000000000000000000000000000000000000008552169283600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115610f9e575f916112ab575b5015611283576040517f4dedf20e000000000000000000000000000000000000000000000000000000008152336004820152602081602481875afa908115610f9e575f91611264575b501561123c5761120c73ffffffffffffffffffffffffffffffffffffffff92845f52600260205260405f208484165f5260205260405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b60405193845216917fcb0caee6dfd90d41657a1c2834c4139aff2ad434ddb51eecd2ea298d3580953e60203392a4005b7f82b42900000000000000000000000000000000000000000000000000000000005f5260045ffd5b61127d915060203d60201161080d576107ff818361195e565b856111a5565b7f1a9141e7000000000000000000000000000000000000000000000000000000005f5260045ffd5b6112c4915060203d60201161080d576107ff818361195e565b8561115c565b3461037c575f7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c57602060405173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b3461037c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c5761136f6118f7565b60243567ffffffffffffffff81169081810361037c5773ffffffffffffffffffffffffffffffffffffffff604051937f5edec50d000000000000000000000000000000000000000000000000000000008552169283600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115610f9e575f9161152d575b5015611283576040517f4dedf20e000000000000000000000000000000000000000000000000000000008152336004820152602081602481875afa908115610f9e575f9161150e575b501561123c57670de0b6b3a764000082116114e657825f52600360205260405f20907fffffffffffffffffffffffffffffffffffffffffffffff0000000000000000ff68ffffffffffffffff0083549260081b1691161790556040519081527f87592866e19f1c7e3aba38aff71910bf6cde4d2aea6dd48bacc5d21b59f68b8c60203392a3005b7f516e7f38000000000000000000000000000000000000000000000000000000005f5260045ffd5b611527915060203d60201161080d576107ff818361195e565b8461145f565b611546915060203d60201161080d576107ff818361195e565b84611416565b3461037c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c5773ffffffffffffffffffffffffffffffffffffffff6115986118f7565b165f52600160205260405f206024355f52602052602060ff60405f2054166040519015158152f35b3461037c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c576115f76118f7565b73ffffffffffffffffffffffffffffffffffffffff61161461191a565b91165f52600260205273ffffffffffffffffffffffffffffffffffffffff60405f2091165f52602052602060ff60405f2054166040519015158152f35b3461037c576101007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c576116896118f7565b61169161191a565b60a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc36011261037c5760e4358015159081810361037c5773ffffffffffffffffffffffffffffffffffffffff604051947f5edec50d000000000000000000000000000000000000000000000000000000008652169384600482015260208160248173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa908115610f9e575f9161186f575b5015611283576040517f4dedf20e000000000000000000000000000000000000000000000000000000008152336004820152602081602481885afa908115610f9e575f91611850575b501561123c576117fb90845f52600160205260405f206117c285611c02565b5f5260205260405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b73ffffffffffffffffffffffffffffffffffffffff60405192168252611823602083016119e4565b60c08201527facfd800238adbc79248c080c459b374b06feb519a69654529b318273686e1ab660e03392a3005b611869915060203d60201161080d576107ff818361195e565b856117a3565b611888915060203d60201161080d576107ff818361195e565b8561175a565b3461037c5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261037c5760209073ffffffffffffffffffffffffffffffffffffffff6118dd6118f7565b165f525f825260405f206024355f52825260405f20548152f35b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361037c57565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361037c57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361037c57565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761199f57604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b9081602091031261037c5751801515810361037c5790565b60443573ffffffffffffffffffffffffffffffffffffffff811680910361037c57815260643573ffffffffffffffffffffffffffffffffffffffff811680910361037c57602082015260843573ffffffffffffffffffffffffffffffffffffffff811680910361037c57604082015260a43573ffffffffffffffffffffffffffffffffffffffff811680910361037c576060820152608060c435910152565b6080809173ffffffffffffffffffffffffffffffffffffffff611aa58261193d565b16845273ffffffffffffffffffffffffffffffffffffffff611ac96020830161193d565b16602085015273ffffffffffffffffffffffffffffffffffffffff611af06040830161193d565b16604085015273ffffffffffffffffffffffffffffffffffffffff611b176060830161193d565b1660608501520135910152565b9160807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f60206fffffffffffffffffffffffffffffffff9473ffffffffffffffffffffffffffffffffffffffff6040979a999a16885260608289015280519182918260608b0152018589015e5f84828901015201168401019416910152565b3d15611bfd573d9067ffffffffffffffff821161199f5760405191611bf260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116018461195e565b82523d5f602084013e565b606090565b60405173ffffffffffffffffffffffffffffffffffffffff602082019260e0845260116101008401527f746869732f6d61726b6574506172616d73000000000000000000000000000000610120840152166040820152611c66606082016044611a83565b6101208152611c776101408261195e565b51902090565b818102918183041490151715611cad57670de0b6b3a763ffff8101809111611cad57670de0b6b3a7640000900490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b90813b15611ddc575f809493819473ffffffffffffffffffffffffffffffffffffffff604051928160208501967f23b872dd000000000000000000000000000000000000000000000000000000008852166024850152166044830152606482015260648152611d4a60848261195e565b51925af1611d56611ba5565b9015611db4578051908115918215611d9a575b505015611d7257565b7f1eded19c000000000000000000000000000000000000000000000000000000005f5260045ffd5b611dad92506020809183010191016119cc565b5f80611d69565b7fe65b7a77000000000000000000000000000000000000000000000000000000005f5260045ffd5b7ff046a714000000000000000000000000000000000000000000000000000000005f5260045ffdfea164736f6c634300081c000a0000000000000000000000004501125508079a99ebbebce205dec9593c2b5857","name":"BluePublicAllocator","is_blueprint":false,"license_type":"none","is_fully_verified":false,"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/vault-v2/lib/morpho-blue/src/interfaces/IMorpho.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\ntype Id is bytes32;\n\nstruct MarketParams {\n    address loanToken;\n    address collateralToken;\n    address oracle;\n    address irm;\n    uint256 lltv;\n}\n\n/// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest\n/// accrual.\nstruct Position {\n    uint256 supplyShares;\n    uint128 borrowShares;\n    uint128 collateral;\n}\n\n/// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual.\n/// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual.\n/// @dev Warning: `totalSupplyShares` does not contain the additional shares accrued by `feeRecipient` since the last\n/// interest accrual.\nstruct Market {\n    uint128 totalSupplyAssets;\n    uint128 totalSupplyShares;\n    uint128 totalBorrowAssets;\n    uint128 totalBorrowShares;\n    uint128 lastUpdate;\n    uint128 fee;\n}\n\nstruct Authorization {\n    address authorizer;\n    address authorized;\n    bool isAuthorized;\n    uint256 nonce;\n    uint256 deadline;\n}\n\nstruct Signature {\n    uint8 v;\n    bytes32 r;\n    bytes32 s;\n}\n\n/// @dev This interface is used for factorizing IMorphoStaticTyping and IMorpho.\n/// @dev Consider using the IMorpho interface instead of this one.\ninterface IMorphoBase {\n    /// @notice The EIP-712 domain separator.\n    /// @dev Warning: Every EIP-712 signed message based on this domain separator can be reused on chains sharing the\n    /// same chain id and on forks because the domain separator would be the same.\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n\n    /// @notice The owner of the contract.\n    /// @dev It has the power to change the owner.\n    /// @dev It has the power to set fees on markets and set the fee recipient.\n    /// @dev It has the power to enable but not disable IRMs and LLTVs.\n    function owner() external view returns (address);\n\n    /// @notice The fee recipient of all markets.\n    /// @dev The recipient receives the fees of a given market through a supply position on that market.\n    function feeRecipient() external view returns (address);\n\n    /// @notice Whether the `irm` is enabled.\n    function isIrmEnabled(address irm) external view returns (bool);\n\n    /// @notice Whether the `lltv` is enabled.\n    function isLltvEnabled(uint256 lltv) external view returns (bool);\n\n    /// @notice Whether `authorized` is authorized to modify `authorizer`'s position on all markets.\n    /// @dev Anyone is authorized to modify their own positions, regardless of this variable.\n    function isAuthorized(address authorizer, address authorized) external view returns (bool);\n\n    /// @notice The `authorizer`'s current nonce. Used to prevent replay attacks with EIP-712 signatures.\n    function nonce(address authorizer) external view returns (uint256);\n\n    /// @notice Sets `newOwner` as `owner` of the contract.\n    /// @dev Warning: No two-step transfer ownership.\n    /// @dev Warning: The owner can be set to the zero address.\n    function setOwner(address newOwner) external;\n\n    /// @notice Enables `irm` as a possible IRM for market creation.\n    /// @dev Warning: It is not possible to disable an IRM.\n    function enableIrm(address irm) external;\n\n    /// @notice Enables `lltv` as a possible LLTV for market creation.\n    /// @dev Warning: It is not possible to disable a LLTV.\n    function enableLltv(uint256 lltv) external;\n\n    /// @notice Sets the `newFee` for the given market `marketParams`.\n    /// @param newFee The new fee, scaled by WAD.\n    /// @dev Warning: The recipient can be the zero address.\n    function setFee(MarketParams memory marketParams, uint256 newFee) external;\n\n    /// @notice Sets `newFeeRecipient` as `feeRecipient` of the fee.\n    /// @dev Warning: If the fee recipient is set to the zero address, fees will accrue there and will be lost.\n    /// @dev Modifying the fee recipient will allow the new recipient to claim any pending fees not yet accrued. To\n    /// ensure that the current recipient receives all due fees, accrue interest manually prior to making any changes.\n    function setFeeRecipient(address newFeeRecipient) external;\n\n    /// @notice Creates the market `marketParams`.\n    /// @dev Here is the list of assumptions on the market's dependencies (tokens, IRM and oracle) that guarantees\n    /// Morpho behaves as expected:\n    /// - The token should be ERC-20 compliant, except that it can omit return values on `transfer` and `transferFrom`.\n    /// - The token balance of Morpho should only decrease on `transfer` and `transferFrom`. In particular, tokens with\n    /// burn functions are not supported.\n    /// - The token should not re-enter Morpho on `transfer` nor `transferFrom`.\n    /// - The token balance of the sender (resp. receiver) should decrease (resp. increase) by exactly the given amount\n    /// on `transfer` and `transferFrom`. In particular, tokens with fees on transfer are not supported.\n    /// - The IRM should not re-enter Morpho.\n    /// - The oracle should return a price with the correct scaling.\n    /// - The oracle price should not be able to change instantly such that the new price is less than the old price\n    /// multiplied by LLTV*LIF. In particular, if the loan asset is a vault that can receive donations, the oracle\n    /// should not price its shares using the AUM.\n    /// @dev Here is a list of assumptions on the market's dependencies which, if broken, could break Morpho's liveness\n    /// properties (funds could get stuck):\n    /// - The token should not revert on `transfer` and `transferFrom` if balances and approvals are right.\n    /// - The amount of assets supplied and borrowed should not be too high (max ~1e32), otherwise the number of shares\n    /// might not fit within 128 bits.\n    /// - The IRM should not revert on `borrowRate`.\n    /// - The IRM should not return a very high borrow rate (otherwise the computation of `interest` in\n    /// `_accrueInterest` can overflow).\n    /// - The oracle should not revert `price`.\n    /// - The oracle should not return a very high price (otherwise the computation of `maxBorrow` in `_isHealthy` or of\n    /// `assetsRepaid` in `liquidate` can overflow).\n    /// @dev The borrow share price of a market with less than 1e4 assets borrowed can be decreased by manipulations, to\n    /// the point where `totalBorrowShares` is very large and borrowing overflows.\n    function createMarket(MarketParams memory marketParams) external;\n\n    /// @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's\n    /// `onMorphoSupply` function with the given `data`.\n    /// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the\n    /// caller is guaranteed to have `assets` tokens pulled from their balance, but the possibility to mint a specific\n    /// amount of shares is given for full compatibility and precision.\n    /// @dev Supplying a large amount can revert for overflow.\n    /// @dev Supplying an amount of shares may lead to supply more or fewer assets than expected due to slippage.\n    /// Consider using the `assets` parameter to avoid this.\n    /// @param marketParams The market to supply assets to.\n    /// @param assets The amount of assets to supply.\n    /// @param shares The amount of shares to mint.\n    /// @param onBehalf The address that will own the increased supply position.\n    /// @param data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed.\n    /// @return assetsSupplied The amount of assets supplied.\n    /// @return sharesSupplied The amount of shares minted.\n    function supply(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        bytes memory data\n    ) external returns (uint256 assetsSupplied, uint256 sharesSupplied);\n\n    /// @notice Withdraws `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`.\n    /// @dev Either `assets` or `shares` should be zero. To withdraw max, pass the `shares`'s balance of `onBehalf`.\n    /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.\n    /// @dev Withdrawing an amount corresponding to more shares than supplied will revert for underflow.\n    /// @dev It is advised to use the `shares` input when withdrawing the full position to avoid reverts due to\n    /// conversion roundings between shares and assets.\n    /// @param marketParams The market to withdraw assets from.\n    /// @param assets The amount of assets to withdraw.\n    /// @param shares The amount of shares to burn.\n    /// @param onBehalf The address of the owner of the supply position.\n    /// @param receiver The address that will receive the withdrawn assets.\n    /// @return assetsWithdrawn The amount of assets withdrawn.\n    /// @return sharesWithdrawn The amount of shares burned.\n    function withdraw(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        address receiver\n    ) external returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn);\n\n    /// @notice Borrows `assets` or `shares` on behalf of `onBehalf` and sends the assets to `receiver`.\n    /// @dev Either `assets` or `shares` should be zero. Most use cases should rely on `assets` as an input so the\n    /// caller is guaranteed to borrow `assets` of tokens, but the possibility to mint a specific amount of shares is\n    /// given for full compatibility and precision.\n    /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.\n    /// @dev Borrowing a large amount can revert for overflow.\n    /// @dev Borrowing an amount of shares may lead to borrow fewer assets than expected due to slippage.\n    /// Consider using the `assets` parameter to avoid this.\n    /// @param marketParams The market to borrow assets from.\n    /// @param assets The amount of assets to borrow.\n    /// @param shares The amount of shares to mint.\n    /// @param onBehalf The address that will own the increased borrow position.\n    /// @param receiver The address that will receive the borrowed assets.\n    /// @return assetsBorrowed The amount of assets borrowed.\n    /// @return sharesBorrowed The amount of shares minted.\n    function borrow(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        address receiver\n    ) external returns (uint256 assetsBorrowed, uint256 sharesBorrowed);\n\n    /// @notice Repays `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's\n    /// `onMorphoRepay` function with the given `data`.\n    /// @dev Either `assets` or `shares` should be zero. To repay max, pass the `shares`'s balance of `onBehalf`.\n    /// @dev Repaying an amount corresponding to more shares than borrowed will revert for underflow.\n    /// @dev It is advised to use the `shares` input when repaying the full position to avoid reverts due to conversion\n    /// roundings between shares and assets.\n    /// @dev An attacker can front-run a repay with a small repay making the transaction revert for underflow.\n    /// @param marketParams The market to repay assets to.\n    /// @param assets The amount of assets to repay.\n    /// @param shares The amount of shares to burn.\n    /// @param onBehalf The address of the owner of the debt position.\n    /// @param data Arbitrary data to pass to the `onMorphoRepay` callback. Pass empty data if not needed.\n    /// @return assetsRepaid The amount of assets repaid.\n    /// @return sharesRepaid The amount of shares burned.\n    function repay(\n        MarketParams memory marketParams,\n        uint256 assets,\n        uint256 shares,\n        address onBehalf,\n        bytes memory data\n    ) external returns (uint256 assetsRepaid, uint256 sharesRepaid);\n\n    /// @notice Supplies `assets` of collateral on behalf of `onBehalf`, optionally calling back the caller's\n    /// `onMorphoSupplyCollateral` function with the given `data`.\n    /// @dev Interest are not accrued since it's not required and it saves gas.\n    /// @dev Supplying a large amount can revert for overflow.\n    /// @param marketParams The market to supply collateral to.\n    /// @param assets The amount of collateral to supply.\n    /// @param onBehalf The address that will own the increased collateral position.\n    /// @param data Arbitrary data to pass to the `onMorphoSupplyCollateral` callback. Pass empty data if not needed.\n    function supplyCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, bytes memory data)\n        external;\n\n    /// @notice Withdraws `assets` of collateral on behalf of `onBehalf` and sends the assets to `receiver`.\n    /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.\n    /// @dev Withdrawing an amount corresponding to more collateral than supplied will revert for underflow.\n    /// @param marketParams The market to withdraw collateral from.\n    /// @param assets The amount of collateral to withdraw.\n    /// @param onBehalf The address of the owner of the collateral position.\n    /// @param receiver The address that will receive the collateral assets.\n    function withdrawCollateral(MarketParams memory marketParams, uint256 assets, address onBehalf, address receiver)\n        external;\n\n    /// @notice Liquidates the given `repaidShares` of debt asset or seize the given `seizedAssets` of collateral on the\n    /// given market `marketParams` of the given `borrower`'s position, optionally calling back the caller's\n    /// `onMorphoLiquidate` function with the given `data`.\n    /// @dev Either `seizedAssets` or `repaidShares` should be zero.\n    /// @dev Seizing more than the collateral balance will underflow and revert without any error message.\n    /// @dev Repaying more than the borrow balance will underflow and revert without any error message.\n    /// @dev An attacker can front-run a liquidation with a small repay making the transaction revert for underflow.\n    /// @param marketParams The market of the position.\n    /// @param borrower The owner of the position.\n    /// @param seizedAssets The amount of collateral to seize.\n    /// @param repaidShares The amount of shares to repay.\n    /// @param data Arbitrary data to pass to the `onMorphoLiquidate` callback. Pass empty data if not needed.\n    /// @return The amount of assets seized.\n    /// @return The amount of assets repaid.\n    function liquidate(\n        MarketParams memory marketParams,\n        address borrower,\n        uint256 seizedAssets,\n        uint256 repaidShares,\n        bytes memory data\n    ) external returns (uint256, uint256);\n\n    /// @notice Executes a flash loan.\n    /// @dev Flash loans have access to the whole balance of the contract (the liquidity and deposited collateral of all\n    /// markets combined, plus donations).\n    /// @dev Warning: Not ERC-3156 compliant but compatibility is easily reached:\n    /// - `flashFee` is zero.\n    /// - `maxFlashLoan` is the token's balance of this contract.\n    /// - The receiver of `assets` is the caller.\n    /// @param token The token to flash loan.\n    /// @param assets The amount of assets to flash loan.\n    /// @param data Arbitrary data to pass to the `onMorphoFlashLoan` callback.\n    function flashLoan(address token, uint256 assets, bytes calldata data) external;\n\n    /// @notice Sets the authorization for `authorized` to manage `msg.sender`'s positions.\n    /// @param authorized The authorized address.\n    /// @param newIsAuthorized The new authorization status.\n    function setAuthorization(address authorized, bool newIsAuthorized) external;\n\n    /// @notice Sets the authorization for `authorization.authorized` to manage `authorization.authorizer`'s positions.\n    /// @dev Warning: Reverts if the signature has already been submitted.\n    /// @dev The signature is malleable, but it has no impact on the security here.\n    /// @dev The nonce is passed as argument to be able to revert with a different error message.\n    /// @param authorization The `Authorization` struct.\n    /// @param signature The signature.\n    function setAuthorizationWithSig(Authorization calldata authorization, Signature calldata signature) external;\n\n    /// @notice Accrues interest for the given market `marketParams`.\n    function accrueInterest(MarketParams memory marketParams) external;\n\n    /// @notice Returns the data stored on the different `slots`.\n    function extSloads(bytes32[] memory slots) external view returns (bytes32[] memory);\n}\n\n/// @dev This interface is inherited by Morpho so that function signatures are checked by the compiler.\n/// @dev Consider using the IMorpho interface instead of this one.\ninterface IMorphoStaticTyping is IMorphoBase {\n    /// @notice The state of the position of `user` on the market corresponding to `id`.\n    /// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest\n    /// accrual.\n    function position(Id id, address user)\n        external\n        view\n        returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral);\n\n    /// @notice The state of the market corresponding to `id`.\n    /// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last interest\n    /// accrual.\n    function market(Id id)\n        external\n        view\n        returns (\n            uint128 totalSupplyAssets,\n            uint128 totalSupplyShares,\n            uint128 totalBorrowAssets,\n            uint128 totalBorrowShares,\n            uint128 lastUpdate,\n            uint128 fee\n        );\n\n    /// @notice The market params corresponding to `id`.\n    /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer\n    /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`.\n    function idToMarketParams(Id id)\n        external\n        view\n        returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv);\n}\n\n/// @title IMorpho\n/// @author Morpho Labs\n/// @custom:contact security@morpho.org\n/// @dev Use this interface for Morpho to have access to all the functions with the appropriate function signatures.\ninterface IMorpho is IMorphoBase {\n    /// @notice The state of the position of `user` on the market corresponding to `id`.\n    /// @dev Warning: For `feeRecipient`, `p.supplyShares` does not contain the accrued shares since the last interest\n    /// accrual.\n    function position(Id id, address user) external view returns (Position memory p);\n\n    /// @notice The state of the market corresponding to `id`.\n    /// @dev Warning: `m.totalSupplyAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `m.totalBorrowAssets` does not contain the accrued interest since the last interest accrual.\n    /// @dev Warning: `m.totalSupplyShares` does not contain the accrued shares by `feeRecipient` since the last\n    /// interest accrual.\n    function market(Id id) external view returns (Market memory m);\n\n    /// @notice The market params corresponding to `id`.\n    /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer\n    /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`.\n    function idToMarketParams(Id id) external view returns (MarketParams memory);\n}\n"},{"file_path":"lib/vault-v2/src/interfaces/IERC20.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\n// Copyright (c) 2025 Morpho Association\npragma solidity >=0.5.0;\n\ninterface IERC20 {\n    function decimals() external view returns (uint8);\n    function name() external view returns (string memory);\n    function symbol() external view returns (string memory);\n    function totalSupply() external view returns (uint256);\n    function balanceOf(address account) external view returns (uint256);\n    function transfer(address to, uint256 shares) external returns (bool success);\n    function transferFrom(address from, address to, uint256 shares) external returns (bool success);\n    function approve(address spender, uint256 shares) external returns (bool success);\n    function allowance(address owner, address spender) external view returns (uint256);\n}\n"},{"file_path":"lib/vault-v2/src/interfaces/IERC2612.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\n// Copyright (c) 2025 Morpho Association\npragma solidity >=0.5.0;\n\ninterface IERC2612 {\n    function permit(address owner, address spender, uint256 shares, uint256 deadline, uint8 v, bytes32 r, bytes32 s)\n        external;\n    function nonces(address owner) external view returns (uint256);\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"},{"file_path":"lib/vault-v2/src/interfaces/IERC4626.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\n// Copyright (c) 2025 Morpho Association\npragma solidity >=0.5.0;\n\nimport {IERC20} from \"./IERC20.sol\";\n\ninterface IERC4626 is IERC20 {\n    function asset() external view returns (address);\n    function totalAssets() external view returns (uint256);\n    function convertToAssets(uint256 shares) external view returns (uint256 assets);\n    function convertToShares(uint256 assets) external view returns (uint256 shares);\n    function deposit(uint256 assets, address onBehalf) external returns (uint256 shares);\n    function mint(uint256 shares, address onBehalf) external returns (uint256 assets);\n    function withdraw(uint256 assets, address receiver, address onBehalf) external returns (uint256 shares);\n    function redeem(uint256 shares, address receiver, address onBehalf) external returns (uint256 assets);\n    function previewDeposit(uint256 assets) external view returns (uint256 shares);\n    function previewMint(uint256 shares) external view returns (uint256 assets);\n    function previewWithdraw(uint256 assets) external view returns (uint256 shares);\n    function previewRedeem(uint256 shares) external view returns (uint256 assets);\n    function maxDeposit(address onBehalf) external view returns (uint256 assets);\n    function maxMint(address onBehalf) external view returns (uint256 shares);\n    function maxWithdraw(address onBehalf) external view returns (uint256 assets);\n    function maxRedeem(address onBehalf) external view returns (uint256 shares);\n}\n"},{"file_path":"lib/vault-v2/src/interfaces/IVaultV2.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\n// Copyright (c) 2025 Morpho Association\npragma solidity >=0.5.0;\n\nimport {IERC4626} from \"./IERC4626.sol\";\nimport {IERC2612} from \"./IERC2612.sol\";\n\nstruct Caps {\n    uint256 allocation;\n    uint128 absoluteCap;\n    uint128 relativeCap;\n}\n\ninterface IVaultV2 is IERC4626, IERC2612 {\n    // State variables\n    function virtualShares() external view returns (uint256);\n    function owner() external view returns (address);\n    function curator() external view returns (address);\n    function receiveSharesGate() external view returns (address);\n    function sendSharesGate() external view returns (address);\n    function receiveAssetsGate() external view returns (address);\n    function sendAssetsGate() external view returns (address);\n    function adapterRegistry() external view returns (address);\n    function isSentinel(address account) external view returns (bool);\n    function isAllocator(address account) external view returns (bool);\n    function firstTotalAssets() external view returns (uint256);\n    function _totalAssets() external view returns (uint128);\n    function lastUpdate() external view returns (uint64);\n    function maxRate() external view returns (uint64);\n    function adapters(uint256 index) external view returns (address);\n    function adaptersLength() external view returns (uint256);\n    function isAdapter(address account) external view returns (bool);\n    function allocation(bytes32 id) external view returns (uint256);\n    function absoluteCap(bytes32 id) external view returns (uint256);\n    function relativeCap(bytes32 id) external view returns (uint256);\n    function forceDeallocatePenalty(address adapter) external view returns (uint256);\n    function liquidityAdapter() external view returns (address);\n    function liquidityData() external view returns (bytes memory);\n    function timelock(bytes4 selector) external view returns (uint256);\n    function abdicated(bytes4 selector) external view returns (bool);\n    function executableAt(bytes memory data) external view returns (uint256);\n    function performanceFee() external view returns (uint96);\n    function performanceFeeRecipient() external view returns (address);\n    function managementFee() external view returns (uint96);\n    function managementFeeRecipient() external view returns (address);\n\n    // Gating\n    function canSendShares(address account) external view returns (bool);\n    function canReceiveShares(address account) external view returns (bool);\n    function canSendAssets(address account) external view returns (bool);\n    function canReceiveAssets(address account) external view returns (bool);\n\n    // Multicall\n    function multicall(bytes[] memory data) external;\n\n    // Owner functions\n    function setOwner(address newOwner) external;\n    function setCurator(address newCurator) external;\n    function setIsSentinel(address account, bool isSentinel) external;\n    function setName(string memory newName) external;\n    function setSymbol(string memory newSymbol) external;\n\n    // Timelocks for curator functions\n    function submit(bytes memory data) external;\n    function revoke(bytes memory data) external;\n\n    // Curator functions\n    function setIsAllocator(address account, bool newIsAllocator) external;\n    function setReceiveSharesGate(address newReceiveSharesGate) external;\n    function setSendSharesGate(address newSendSharesGate) external;\n    function setReceiveAssetsGate(address newReceiveAssetsGate) external;\n    function setSendAssetsGate(address newSendAssetsGate) external;\n    function setAdapterRegistry(address newAdapterRegistry) external;\n    function addAdapter(address account) external;\n    function removeAdapter(address account) external;\n    function increaseTimelock(bytes4 selector, uint256 newDuration) external;\n    function decreaseTimelock(bytes4 selector, uint256 newDuration) external;\n    function abdicate(bytes4 selector) external;\n    function setPerformanceFee(uint256 newPerformanceFee) external;\n    function setManagementFee(uint256 newManagementFee) external;\n    function setPerformanceFeeRecipient(address newPerformanceFeeRecipient) external;\n    function setManagementFeeRecipient(address newManagementFeeRecipient) external;\n    function increaseAbsoluteCap(bytes memory idData, uint256 newAbsoluteCap) external;\n    function decreaseAbsoluteCap(bytes memory idData, uint256 newAbsoluteCap) external;\n    function increaseRelativeCap(bytes memory idData, uint256 newRelativeCap) external;\n    function decreaseRelativeCap(bytes memory idData, uint256 newRelativeCap) external;\n    function setMaxRate(uint256 newMaxRate) external;\n    function setForceDeallocatePenalty(address adapter, uint256 newForceDeallocatePenalty) external;\n\n    // Allocator functions\n    function allocate(address adapter, bytes memory data, uint256 assets) external;\n    function deallocate(address adapter, bytes memory data, uint256 assets) external;\n    function setLiquidityAdapterAndData(address newLiquidityAdapter, bytes memory newLiquidityData) external;\n\n    // Exchange rate\n    function accrueInterest() external;\n    function accrueInterestView()\n        external\n        view\n        returns (uint256 newTotalAssets, uint256 performanceFeeShares, uint256 managementFeeShares);\n\n    // Force deallocate\n    function forceDeallocate(address adapter, bytes memory data, uint256 assets, address onBehalf)\n        external\n        returns (uint256 penaltyShares);\n}\n"},{"file_path":"lib/vault-v2/src/interfaces/IVaultV2Factory.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\n// Copyright (c) 2025 Morpho Association\npragma solidity >=0.5.0;\n\ninterface IVaultV2Factory {\n    /* EVENTS */\n\n    event CreateVaultV2(address indexed owner, address indexed asset, bytes32 salt, address indexed newVaultV2);\n\n    /* FUNCTIONS */\n\n    function isVaultV2(address account) external view returns (bool);\n    function vaultV2(address owner, address asset, bytes32 salt) external view returns (address);\n    function createVaultV2(address owner, address asset, bytes32 salt) external returns (address newVaultV2);\n}\n"},{"file_path":"lib/vault-v2/src/libraries/ConstantsLib.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\n// Copyright (c) 2025 Morpho Association\npragma solidity ^0.8.0;\n\nuint256 constant WAD = 1e18;\nbytes32 constant DOMAIN_TYPEHASH = keccak256(\"EIP712Domain(uint256 chainId,address verifyingContract)\");\nbytes32 constant PERMIT_TYPEHASH =\n    keccak256(\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\");\nuint256 constant MAX_MAX_RATE = 200e16 / uint256(365 days); // 200% APR\nuint256 constant MAX_PERFORMANCE_FEE = 0.5e18; // 50%\nuint256 constant MAX_MANAGEMENT_FEE = 0.05e18 / uint256(365 days); // 5%\nuint256 constant MAX_FORCE_DEALLOCATE_PENALTY = 0.02e18; // 2%\n"},{"file_path":"lib/vault-v2/src/libraries/ErrorsLib.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\n// Copyright (c) 2025 Morpho Association\npragma solidity ^0.8.0;\n\nlibrary ErrorsLib {\n    error Abdicated();\n    error AbsoluteCapExceeded();\n    error AbsoluteCapNotDecreasing();\n    error AbsoluteCapNotIncreasing();\n    error ApproveReturnedFalse();\n    error ApproveReverted();\n    error AutomaticallyTimelocked();\n    error CannotReceiveShares();\n    error CannotReceiveAssets();\n    error CannotSendShares();\n    error CannotSendAssets();\n    error CapExceeded();\n    error CastOverflow();\n    error DataAlreadyPending();\n    error DataNotTimelocked();\n    error FeeInvariantBroken();\n    error FeeTooHigh();\n    error InvalidSigner();\n    error MaxRateTooHigh();\n    error NoCode();\n    error NotAdapter();\n    error NotInAdapterRegistry();\n    error PenaltyTooHigh();\n    error PermitDeadlineExpired();\n    error RelativeCapAboveOne();\n    error RelativeCapExceeded();\n    error RelativeCapNotDecreasing();\n    error RelativeCapNotIncreasing();\n    error TimelockNotDecreasing();\n    error TimelockNotExpired();\n    error TimelockNotIncreasing();\n    error TransferFromReturnedFalse();\n    error TransferFromReverted();\n    error TransferReturnedFalse();\n    error TransferReverted();\n    error Unauthorized();\n    error ZeroAbsoluteCap();\n    error ZeroAddress();\n    error ZeroAllocation();\n}\n"},{"file_path":"lib/vault-v2/src/libraries/MathLib.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\n// Copyright (c) 2025 Morpho Association\npragma solidity ^0.8.0;\n\nimport {ErrorsLib} from \"./ErrorsLib.sol\";\n\nlibrary MathLib {\n    /// @dev Returns (x * y) / d rounded down.\n    function mulDivDown(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) {\n        return (x * y) / d;\n    }\n\n    /// @dev Returns (x * y) / d rounded up.\n    function mulDivUp(uint256 x, uint256 y, uint256 d) internal pure returns (uint256) {\n        return (x * y + (d - 1)) / d;\n    }\n\n    /// @dev Returns max(0, x - y).\n    function zeroFloorSub(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        assembly {\n            z := mul(gt(x, y), sub(x, y))\n        }\n    }\n\n    /// @dev Casts from uint256 to uint128, reverting if input number is too large.\n    function toUint128(uint256 x) internal pure returns (uint128) {\n        require(x <= type(uint128).max, ErrorsLib.CastOverflow());\n        // forge-lint: disable-next-item(unsafe-typecast) safe because x <= type(uint128).max.\n        return uint128(x);\n    }\n\n    /// @dev Casts from int256 to uint256, reverting if input number is negative.\n    function toUint256(int256 x) internal pure returns (uint256) {\n        require(x >= 0, ErrorsLib.CastOverflow());\n        // forge-lint: disable-next-item(unsafe-typecast) safe because x >= 0.\n        return uint256(x);\n    }\n\n    /// @dev Returns min(x, y).\n    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        assembly {\n            z := xor(x, mul(xor(x, y), lt(y, x)))\n        }\n    }\n}\n"},{"file_path":"lib/vault-v2/src/libraries/SafeERC20Lib.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\n// Copyright (c) 2025 Morpho Association\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"../interfaces/IERC20.sol\";\nimport {ErrorsLib} from \"./ErrorsLib.sol\";\n\nlibrary SafeERC20Lib {\n    function safeTransfer(address token, address to, uint256 value) internal {\n        require(token.code.length > 0, ErrorsLib.NoCode());\n\n        (bool success, bytes memory returndata) = token.call(abi.encodeCall(IERC20.transfer, (to, value)));\n        require(success, ErrorsLib.TransferReverted());\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), ErrorsLib.TransferReturnedFalse());\n    }\n\n    function safeTransferFrom(address token, address from, address to, uint256 value) internal {\n        require(token.code.length > 0, ErrorsLib.NoCode());\n\n        (bool success, bytes memory returndata) = token.call(abi.encodeCall(IERC20.transferFrom, (from, to, value)));\n        require(success, ErrorsLib.TransferFromReverted());\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), ErrorsLib.TransferFromReturnedFalse());\n    }\n\n    function safeApprove(address token, address spender, uint256 value) internal {\n        require(token.code.length > 0, ErrorsLib.NoCode());\n\n        (bool success, bytes memory returndata) = token.call(abi.encodeCall(IERC20.approve, (spender, value)));\n        require(success, ErrorsLib.ApproveReverted());\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), ErrorsLib.ApproveReturnedFalse());\n    }\n}\n"},{"file_path":"lib/vault-v2/src/periphery/blue-public-allocator/interfaces/IBluePublicAllocator.sol","source_code":"// SPDX-License-Identifier: GPL-2.0-or-later\n// Copyright (c) 2026 Morpho Association\npragma solidity >=0.8.0;\n\nimport {MarketParams} from \"../../../../lib/morpho-blue/src/interfaces/IMorpho.sol\";\n\nstruct VaultData {\n    bool canPullFromIdle;\n    uint64 penalty;\n}\n\n// forgefmt: disable-start\ninterface IBluePublicAllocator {\n\n    /* EVENTS */\n\n    event SetAbsoluteCap(address indexed sender, address indexed vault, address adapter, MarketParams marketParams, uint256 absoluteCap);\n    event SetCanPullFromMarket(address indexed sender, address indexed vault, address adapter, MarketParams marketParams, bool canPullFromMarket);\n    event SetCanPullFromIdle(address indexed sender, address indexed vault, bool canPullFromIdle);\n    event SetIsActiveAdapter(address indexed sender, address indexed vault, address indexed adapter, bool isActiveAdapter);\n    event SetPenalty(address indexed sender, address indexed vault, uint64 newPenalty);\n    event Reallocate(address sender, address indexed vault, address deallocateAdapter, bytes32 indexed deallocateId, address allocateAdapter, bytes32 indexed allocateId, uint128 assets, uint256 penaltyAssets);\n    event AllocateFromIdle(address indexed sender, address indexed vault, address adapter, bytes32 indexed allocateId, uint128 assets, uint256 penaltyAssets);\n\n    /* ERRORS */\n\n    error Unauthorized();\n    error AbsoluteCapExceeded();\n    error ZeroAbsoluteCap();\n    error CannotPullFromMarket();\n    error CannotPullFromIdle();\n    error InactiveAdapter();\n    error PenaltyTooHigh();\n    error IncorrectPenalty();\n    error NotVaultV2();\n\n    /* VIEW */\n\n    function vaultV2Factory() external view returns (address);\n    function absoluteCap(address vault, bytes32 id) external view returns (uint256);\n    function canPullFromMarket(address vault, bytes32 id) external view returns (bool);\n    function isActiveAdapter(address vault, address adapter) external view returns (bool);\n    function vaultData(address vault) external view returns (bool canPullFromIdle, uint64 penalty);\n\n    /* FUNCTIONS */\n\n    function multicall(bytes[] calldata data) external;\n    function setIsActiveAdapter(address vault, address adapter, bool newIsActiveAdapter) external;\n    function setAbsoluteCap(address vault, address adapter, MarketParams calldata marketParams, uint256 newAbsoluteCap) external;\n    function setCanPullFromMarket(address vault, address adapter, MarketParams calldata marketParams, bool newCanPullFromMarket) external;\n    function setCanPullFromIdle(address vault, bool newCanPullFromIdle) external;\n    function setPenalty(address vault, uint64 newPenalty) external;\n    function reallocate(address vault, address deallocateAdapter, MarketParams calldata deallocateMarketParams, address allocateAdapter, MarketParams calldata allocateMarketParams, uint128 assets, uint64 penalty) external;\n    function allocateFromIdle(address vault, address adapter, MarketParams calldata marketParams, uint128 assets, uint64 penalty) external;\n}\n// forgefmt: disable-end\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"address","name":"_vaultV2Factory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AbsoluteCapExceeded","type":"error"},{"inputs":[],"name":"CannotPullFromIdle","type":"error"},{"inputs":[],"name":"CannotPullFromMarket","type":"error"},{"inputs":[],"name":"InactiveAdapter","type":"error"},{"inputs":[],"name":"IncorrectPenalty","type":"error"},{"inputs":[],"name":"NoCode","type":"error"},{"inputs":[],"name":"NotVaultV2","type":"error"},{"inputs":[],"name":"PenaltyTooHigh","type":"error"},{"inputs":[],"name":"TransferFromReturnedFalse","type":"error"},{"inputs":[],"name":"TransferFromReverted","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroAbsoluteCap","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"address","name":"adapter","type":"address"},{"indexed":true,"internalType":"bytes32","name":"allocateId","type":"bytes32"},{"indexed":false,"internalType":"uint128","name":"assets","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"penaltyAssets","type":"uint256"}],"name":"AllocateFromIdle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"address","name":"deallocateAdapter","type":"address"},{"indexed":true,"internalType":"bytes32","name":"deallocateId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"allocateAdapter","type":"address"},{"indexed":true,"internalType":"bytes32","name":"allocateId","type":"bytes32"},{"indexed":false,"internalType":"uint128","name":"assets","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"penaltyAssets","type":"uint256"}],"name":"Reallocate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"address","name":"adapter","type":"address"},{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"}],"indexed":false,"internalType":"struct MarketParams","name":"marketParams","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"absoluteCap","type":"uint256"}],"name":"SetAbsoluteCap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"bool","name":"canPullFromIdle","type":"bool"}],"name":"SetCanPullFromIdle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"address","name":"adapter","type":"address"},{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"}],"indexed":false,"internalType":"struct MarketParams","name":"marketParams","type":"tuple"},{"indexed":false,"internalType":"bool","name":"canPullFromMarket","type":"bool"}],"name":"SetCanPullFromMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":true,"internalType":"address","name":"adapter","type":"address"},{"indexed":false,"internalType":"bool","name":"isActiveAdapter","type":"bool"}],"name":"SetIsActiveAdapter","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"uint64","name":"newPenalty","type":"uint64"}],"name":"SetPenalty","type":"event"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"absoluteCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"adapter","type":"address"},{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"}],"internalType":"struct MarketParams","name":"marketParams","type":"tuple"},{"internalType":"uint128","name":"assets","type":"uint128"},{"internalType":"uint64","name":"penalty","type":"uint64"}],"name":"allocateFromIdle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"canPullFromMarket","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"adapter","type":"address"}],"name":"isActiveAdapter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"deallocateAdapter","type":"address"},{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"}],"internalType":"struct MarketParams","name":"deallocateMarketParams","type":"tuple"},{"internalType":"address","name":"allocateAdapter","type":"address"},{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"}],"internalType":"struct MarketParams","name":"allocateMarketParams","type":"tuple"},{"internalType":"uint128","name":"assets","type":"uint128"},{"internalType":"uint64","name":"penalty","type":"uint64"}],"name":"reallocate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"adapter","type":"address"},{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"}],"internalType":"struct MarketParams","name":"marketParams","type":"tuple"},{"internalType":"uint256","name":"newAbsoluteCap","type":"uint256"}],"name":"setAbsoluteCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"bool","name":"newCanPullFromIdle","type":"bool"}],"name":"setCanPullFromIdle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"adapter","type":"address"},{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"}],"internalType":"struct MarketParams","name":"marketParams","type":"tuple"},{"internalType":"bool","name":"newCanPullFromMarket","type":"bool"}],"name":"setCanPullFromMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"adapter","type":"address"},{"internalType":"bool","name":"newIsActiveAdapter","type":"bool"}],"name":"setIsActiveAdapter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint64","name":"newPenalty","type":"uint64"}],"name":"setPenalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"}],"name":"vaultData","outputs":[{"internalType":"bool","name":"canPullFromIdle","type":"bool"},{"internalType":"uint64","name":"penalty","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultV2Factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":true,"constructor_args":"0000000000000000000000004501125508079a99ebbebce205dec9593c2b5857"}