{"sources":{"contracts/MaplePoolManager.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.25;\n\nimport { ERC20Helper }           from \"../modules/erc20-helper/src/ERC20Helper.sol\";\nimport { IMapleProxyFactory }    from \"../modules/maple-proxy-factory/contracts/interfaces/IMapleProxyFactory.sol\";\nimport { IMapleProxied }         from \"../modules/maple-proxy-factory/contracts/interfaces/IMapleProxied.sol\";\nimport { MapleProxiedInternals } from \"../modules/maple-proxy-factory/contracts/MapleProxiedInternals.sol\";\n\nimport { MaplePoolManagerStorage } from \"./proxy/MaplePoolManagerStorage.sol\";\n\nimport {\n    IERC20Like,\n    IGlobalsLike,\n    ILoanLike,\n    ILoanManagerLike,\n    IPoolDelegateCoverLike,\n    IPoolLike,\n    IPoolPermissionManagerLike,\n    IStrategyLike,\n    IWithdrawalManagerLike\n} from \"./interfaces/Interfaces.sol\";\n\nimport { IMaplePoolManager } from \"./interfaces/IMaplePoolManager.sol\";\n\n/*\n\n   ███╗   ███╗ █████╗ ██████╗ ██╗     ███████╗\n   ████╗ ████║██╔══██╗██╔══██╗██║     ██╔════╝\n   ██╔████╔██║███████║██████╔╝██║     █████╗\n   ██║╚██╔╝██║██╔══██║██╔═══╝ ██║     ██╔══╝\n   ██║ ╚═╝ ██║██║  ██║██║     ███████╗███████╗\n   ╚═╝     ╚═╝╚═╝  ╚═╝╚═╝     ╚══════╝╚══════╝\n\n\n   ██████╗  ██████╗  ██████╗ ██╗         ███╗   ███╗ █████╗ ███╗   ██╗ █████╗  ██████╗ ███████╗██████╗\n   ██╔══██╗██╔═══██╗██╔═══██╗██║         ████╗ ████║██╔══██╗████╗  ██║██╔══██╗██╔════╝ ██╔════╝██╔══██╗\n   ██████╔╝██║   ██║██║   ██║██║         ██╔████╔██║███████║██╔██╗ ██║███████║██║  ███╗█████╗  ██████╔╝\n   ██╔═══╝ ██║   ██║██║   ██║██║         ██║╚██╔╝██║██╔══██║██║╚██╗██║██╔══██║██║   ██║██╔══╝  ██╔══██╗\n   ██║     ╚██████╔╝╚██████╔╝███████╗    ██║ ╚═╝ ██║██║  ██║██║ ╚████║██║  ██║╚██████╔╝███████╗██║  ██║\n   ╚═╝      ╚═════╝  ╚═════╝ ╚══════╝    ╚═╝     ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝╚═╝  ╚═╝ ╚═════╝ ╚══════╝╚═╝  ╚═╝\n\n*/\n\ncontract MaplePoolManager is IMaplePoolManager, MapleProxiedInternals, MaplePoolManagerStorage {\n\n    uint256 public constant HUNDRED_PERCENT = 100_0000;  // Four decimal precision.\n\n    /**************************************************************************************************************************************/\n    /*** Modifiers                                                                                                                      ***/\n    /**************************************************************************************************************************************/\n\n    modifier nonReentrant() {\n        require(_locked == 1, \"PM:LOCKED\");\n\n        _locked = 2;\n\n        _;\n\n        _locked = 1;\n    }\n\n    modifier onlyIfNotConfigured() {\n        _revertIfConfigured();\n        _;\n    }\n\n    modifier onlyProtocolAdminsOrNotConfigured() {\n        _revertIfConfiguredAndNotProtocolAdmins();\n        _;\n    }\n\n    modifier onlyPool() {\n        _revertIfNotPool();\n        _;\n    }\n\n    modifier onlyPoolDelegate() {\n        _revertIfNotPoolDelegate();\n        _;\n    }\n\n    modifier onlyPoolDelegateOrProtocolAdmins() {\n        _revertIfNeitherPoolDelegateNorProtocolAdmins();\n        _;\n    }\n\n    modifier whenNotPaused() {\n        _revertIfPaused();\n        _;\n    }\n\n    /**************************************************************************************************************************************/\n    /*** Migration Functions                                                                                                            ***/\n    /**************************************************************************************************************************************/\n\n    // NOTE: Can't add whenProtocolNotPaused modifier here, as globals won't be set until\n    //       initializer.initialize() is called, and this function is what triggers that initialization.\n    function migrate(address migrator_, bytes calldata arguments_) external override whenNotPaused {\n        require(msg.sender == _factory(),        \"PM:M:NOT_FACTORY\");\n        require(_migrate(migrator_, arguments_), \"PM:M:FAILED\");\n        require(poolDelegateCover != address(0), \"PM:M:DELEGATE_NOT_SET\");\n    }\n\n    function setImplementation(address implementation_) external override whenNotPaused {\n        require(msg.sender == _factory(), \"PM:SI:NOT_FACTORY\");\n        _setImplementation(implementation_);\n    }\n\n    function upgrade(uint256 version_, bytes calldata arguments_) external override whenNotPaused {\n        IGlobalsLike globals_ = IGlobalsLike(globals());\n\n        if (msg.sender == poolDelegate) {\n            require(globals_.isValidScheduledCall(msg.sender, address(this), \"PM:UPGRADE\", msg.data), \"PM:U:INVALID_SCHED_CALL\");\n\n            globals_.unscheduleCall(msg.sender, \"PM:UPGRADE\", msg.data);\n        } else {\n            require(msg.sender == globals_.securityAdmin(), \"PM:U:NO_AUTH\");\n        }\n\n        emit Upgraded(version_, arguments_);\n\n        IMapleProxyFactory(_factory()).upgradeInstance(version_, arguments_);\n    }\n\n    /**************************************************************************************************************************************/\n    /*** Initial Configuration Function                                                                                                 ***/\n    /**************************************************************************************************************************************/\n\n    // NOTE: This function is always called atomically during the deployment process so a DoS attack is not possible.\n    function completeConfiguration() external override whenNotPaused onlyIfNotConfigured {\n        configured = true;\n\n        emit PoolConfigurationComplete();\n    }\n\n    /**************************************************************************************************************************************/\n    /*** Ownership Transfer Functions                                                                                                   ***/\n    /**************************************************************************************************************************************/\n\n    function acceptPoolDelegate() external override whenNotPaused {\n        require(msg.sender == pendingPoolDelegate, \"PM:APD:NOT_PENDING_PD\");\n\n        IGlobalsLike(globals()).transferOwnedPoolManager(poolDelegate, msg.sender);\n\n        emit PendingDelegateAccepted(poolDelegate, pendingPoolDelegate);\n\n        poolDelegate        = pendingPoolDelegate;\n        pendingPoolDelegate = address(0);\n    }\n\n    function setPendingPoolDelegate(address pendingPoolDelegate_) external override whenNotPaused onlyPoolDelegateOrProtocolAdmins {\n        pendingPoolDelegate = pendingPoolDelegate_;\n\n        emit PendingDelegateSet(poolDelegate, pendingPoolDelegate_);\n    }\n\n    /**************************************************************************************************************************************/\n    /*** Globals Admin Functions                                                                                                        ***/\n    /**************************************************************************************************************************************/\n\n    function setActive(bool active_) external override whenNotPaused {\n        require(msg.sender == globals(), \"PM:SA:NOT_GLOBALS\");\n        emit SetAsActive(active = active_);\n    }\n\n    /**************************************************************************************************************************************/\n    /*** Pool Delegate Admin Functions                                                                                                  ***/\n    /**************************************************************************************************************************************/\n\n    function addStrategy(address strategyFactory_, bytes calldata extraDeploymentData_)\n        external override whenNotPaused onlyProtocolAdminsOrNotConfigured returns (address strategy_)\n    {\n        require(IGlobalsLike(globals()).isInstanceOf(\"STRATEGY_FACTORY\", strategyFactory_), \"PM:AS:INVALID_FACTORY\");\n\n        // NOTE: If removing strategies is allowed in the future, there will be a need to rethink salts here due to collisions.\n        strategy_ = IMapleProxyFactory(strategyFactory_).createInstance(\n            bytes.concat(abi.encode(address(this)), extraDeploymentData_),\n            keccak256(abi.encode(address(this), strategyList.length))\n        );\n\n        isStrategy[strategy_] = true;\n\n        strategyList.push(strategy_);\n\n        emit StrategyAdded(strategy_);\n    }\n\n    function setDelegateManagementFeeRate(uint256 delegateManagementFeeRate_)\n        external override whenNotPaused onlyProtocolAdminsOrNotConfigured\n    {\n        require(delegateManagementFeeRate_ <= HUNDRED_PERCENT, \"PM:SDMFR:OOB\");\n\n        emit DelegateManagementFeeRateSet(delegateManagementFeeRate = delegateManagementFeeRate_);\n    }\n\n    function setIsStrategy(address strategy_, bool isStrategy_) external override whenNotPaused onlyPoolDelegateOrProtocolAdmins {\n        emit IsStrategySet(strategy_, isStrategy[strategy_] = isStrategy_);\n\n        // Check Strategy is in the list.\n        // NOTE: The factory and instance check are not required as the mapping is being updated for a Strategy that is in the list.\n        for (uint256 i_; i_ < strategyList.length; ++i_) {\n            if (strategyList[i_] == strategy_) return;\n        }\n\n        revert(\"PM:SIS:INVALID_STRATEGY\");\n    }\n\n    function setLiquidityCap(uint256 liquidityCap_) external override whenNotPaused onlyProtocolAdminsOrNotConfigured {\n        emit LiquidityCapSet(liquidityCap = liquidityCap_);\n    }\n\n    function setWithdrawalManager(address withdrawalManager_) external override whenNotPaused onlyIfNotConfigured {\n        address factory_ = IMapleProxied(withdrawalManager_).factory();\n\n        require(IGlobalsLike(globals()).isInstanceOf(\"WITHDRAWAL_MANAGER_FACTORY\", factory_), \"PM:SWM:INVALID_FACTORY\");\n        require(IMapleProxyFactory(factory_).isInstance(withdrawalManager_),                  \"PM:SWM:INVALID_INSTANCE\");\n\n        emit WithdrawalManagerSet(withdrawalManager = withdrawalManager_);\n    }\n\n    function setPoolPermissionManager(address poolPermissionManager_) external override whenNotPaused onlyProtocolAdminsOrNotConfigured {\n        require(IGlobalsLike(globals()).isInstanceOf(\"POOL_PERMISSION_MANAGER\", poolPermissionManager_), \"PM:SPPM:INVALID_INSTANCE\");\n\n        emit PoolPermissionManagerSet(poolPermissionManager = poolPermissionManager_);\n    }\n\n    /**************************************************************************************************************************************/\n    /*** Funding Functions                                                                                                              ***/\n    /**************************************************************************************************************************************/\n\n    function requestFunds(address destination_, uint256 principal_) external override whenNotPaused nonReentrant {\n        address asset_   = asset;\n        address pool_    = pool;\n        address factory_ = IMapleProxied(msg.sender).factory();\n\n        IGlobalsLike globals_ = IGlobalsLike(globals());\n\n        // NOTE: Do not need to check isInstance() as the Strategy is added to the list on `addStrategy()` or `configure()`.\n        require(principal_ != 0,                                     \"PM:RF:INVALID_PRINCIPAL\");\n        require(globals_.isInstanceOf(\"STRATEGY_FACTORY\", factory_), \"PM:RF:INVALID_FACTORY\");\n        require(IMapleProxyFactory(factory_).isInstance(msg.sender), \"PM:RF:INVALID_INSTANCE\");\n        require(isStrategy[msg.sender],                              \"PM:RF:NOT_STRATEGY\");\n        require(IERC20Like(pool_).totalSupply() != 0,                \"PM:RF:ZERO_SUPPLY\");\n        require(_hasSufficientCover(address(globals_), asset_),      \"PM:RF:INSUFFICIENT_COVER\");\n\n        // Fetching locked liquidity needs to be done prior to transferring the tokens.\n        uint256 lockedLiquidity_ = IWithdrawalManagerLike(withdrawalManager).lockedLiquidity();\n\n        // Transfer the required principal.\n        require(destination_ != address(0),                                        \"PM:RF:INVALID_DESTINATION\");\n        require(ERC20Helper.transferFrom(asset_, pool_, destination_, principal_), \"PM:RF:TRANSFER_FAIL\");\n\n        // The remaining liquidity in the pool must be greater or equal to the locked liquidity.\n        require(IERC20Like(asset_).balanceOf(pool_) >= lockedLiquidity_, \"PM:RF:LOCKED_LIQUIDITY\");\n    }\n\n    /**************************************************************************************************************************************/\n    /*** Loan Default Functions                                                                                                         ***/\n    /**************************************************************************************************************************************/\n\n    function finishCollateralLiquidation(address loan_) external override whenNotPaused nonReentrant onlyPoolDelegateOrProtocolAdmins {\n        ( uint256 losses_, uint256 platformFees_ ) = ILoanManagerLike(_getLoanManager(loan_)).finishCollateralLiquidation(loan_);\n\n        _handleCover(losses_, platformFees_);\n\n        emit CollateralLiquidationFinished(loan_, losses_);\n    }\n\n    function triggerDefault(address loan_, address liquidatorFactory_)\n        external override whenNotPaused nonReentrant onlyPoolDelegateOrProtocolAdmins\n    {\n        require(IGlobalsLike(globals()).isInstanceOf(\"LIQUIDATOR_FACTORY\", liquidatorFactory_), \"PM:TD:NOT_FACTORY\");\n\n        (\n            bool    liquidationComplete_,\n            uint256 losses_,\n            uint256 platformFees_\n        ) = ILoanManagerLike(_getLoanManager(loan_)).triggerDefault(loan_, liquidatorFactory_);\n\n        if (!liquidationComplete_) {\n            emit CollateralLiquidationTriggered(loan_);\n            return;\n        }\n\n        _handleCover(losses_, platformFees_);\n\n        emit CollateralLiquidationFinished(loan_, losses_);\n    }\n\n    /**************************************************************************************************************************************/\n    /*** Pool Exit Functions                                                                                                            ***/\n    /**************************************************************************************************************************************/\n\n    function processRedeem(uint256 shares_, address owner_, address sender_)\n        external override whenNotPaused nonReentrant onlyPool returns (uint256 redeemableShares_, uint256 resultingAssets_)\n    {\n        require(owner_ == sender_ || IPoolLike(pool).allowance(owner_, sender_) > 0, \"PM:PR:NO_ALLOWANCE\");\n\n        ( redeemableShares_, resultingAssets_ ) = IWithdrawalManagerLike(withdrawalManager).processExit(shares_, owner_);\n        emit RedeemProcessed(owner_, redeemableShares_, resultingAssets_);\n    }\n\n    function processWithdraw(uint256 assets_, address owner_, address sender_)\n        external override whenNotPaused nonReentrant returns (uint256 redeemableShares_, uint256 resultingAssets_)\n    {\n        assets_; owner_; sender_; redeemableShares_; resultingAssets_;  // Silence compiler warnings\n        require(false, \"PM:PW:NOT_ENABLED\");\n    }\n\n    function removeShares(uint256 shares_, address owner_)\n        external override whenNotPaused nonReentrant onlyPool returns (uint256 sharesReturned_)\n    {\n        emit SharesRemoved(\n            owner_,\n            sharesReturned_ = IWithdrawalManagerLike(withdrawalManager).removeShares(shares_, owner_)\n        );\n    }\n\n    function requestRedeem(uint256 shares_, address owner_, address sender_) external override whenNotPaused nonReentrant onlyPool {\n        address pool_ = pool;\n\n        require(ERC20Helper.approve(pool_, withdrawalManager, shares_), \"PM:RR:APPROVE_FAIL\");\n\n        if (sender_ != owner_ && shares_ == 0) {\n            require(IPoolLike(pool_).allowance(owner_, sender_) > 0, \"PM:RR:NO_ALLOWANCE\");\n        }\n\n        IWithdrawalManagerLike(withdrawalManager).addShares(shares_, owner_);\n\n        emit RedeemRequested(owner_, shares_);\n    }\n\n    function requestWithdraw(uint256 shares_, uint256 assets_, address owner_, address sender_)\n        external override whenNotPaused nonReentrant\n    {\n        shares_; assets_; owner_; sender_;  // Silence compiler warnings\n        require(false, \"PM:RW:NOT_ENABLED\");\n    }\n\n    /**************************************************************************************************************************************/\n    /*** Pool Delegate Cover Functions                                                                                                  ***/\n    /**************************************************************************************************************************************/\n\n    function depositCover(uint256 amount_) external override whenNotPaused {\n        require(ERC20Helper.transferFrom(asset, msg.sender, poolDelegateCover, amount_), \"PM:DC:TRANSFER_FAIL\");\n        emit CoverDeposited(amount_);\n    }\n\n    function withdrawCover(uint256 amount_, address recipient_) external override whenNotPaused onlyPoolDelegate {\n        recipient_ = recipient_ == address(0) ? msg.sender : recipient_;\n\n        IPoolDelegateCoverLike(poolDelegateCover).moveFunds(amount_, recipient_);\n\n        require(\n            IERC20Like(asset).balanceOf(poolDelegateCover) >= IGlobalsLike(globals()).minCoverAmount(address(this)),\n            \"PM:WC:BELOW_MIN\"\n        );\n\n        emit CoverWithdrawn(amount_);\n    }\n\n    /**************************************************************************************************************************************/\n    /*** View Functions                                                                                                                 ***/\n    /**************************************************************************************************************************************/\n\n    function canCall(bytes32 functionId_, address caller_, bytes calldata data_)\n        external view override returns (bool canCall_, string memory errorMessage_)\n    {\n        if (IGlobalsLike(globals()).isFunctionPaused(msg.sig)) return (false, \"PM:CC:PAUSED\");\n\n        uint256[3] memory params_ = _decodeParameters(data_);\n\n        uint256 assets_ = params_[0];\n        address lender_ = _address(params_[1]);\n\n        // For mint functions there's a need to convert shares into assets.\n        if (functionId_ == \"P:mint\" || functionId_ == \"P:mintWithPermit\") assets_ = IPoolLike(pool).previewMint(params_[0]);\n\n        // Redeem and withdraw require getting the third word from the calldata.\n        if ( functionId_ == \"P:redeem\" || functionId_ == \"P:withdraw\") lender_ = _address(params_[2]);\n\n        // Transfers need to check both the sender and the recipient.\n        if (functionId_ == \"P:transfer\" || functionId_ == \"P:transferFrom\") {\n            address[] memory lenders_ = new address[](2);\n\n            ( lenders_[0], lenders_[1] ) = functionId_ == \"P:transfer\" ?\n                (caller_,              _address(params_[0])) :\n                (_address(params_[0]), _address(params_[1]));\n\n            // Check both lenders in a single call.\n            if (!IPoolPermissionManagerLike(poolPermissionManager).hasPermission(address(this), lenders_, functionId_)) {\n                return (false, \"PM:CC:NOT_ALLOWED\");\n            }\n\n        } else {\n            if (!IPoolPermissionManagerLike(poolPermissionManager).hasPermission(address(this), lender_, functionId_)) {\n                return (false, \"PM:CC:NOT_ALLOWED\");\n            }\n        }\n\n        if (\n            functionId_ == \"P:redeem\"          ||\n            functionId_ == \"P:withdraw\"        ||\n            functionId_ == \"P:removeShares\"    ||\n            functionId_ == \"P:requestRedeem\"   ||\n            functionId_ == \"P:requestWithdraw\" ||\n            functionId_ == \"P:transfer\"        ||\n            functionId_ == \"P:transferFrom\"\n        ) return (true, \"\");\n\n        if (\n            functionId_ == \"P:deposit\"           ||\n            functionId_ == \"P:depositWithPermit\" ||\n            functionId_ == \"P:mint\"              ||\n            functionId_ == \"P:mintWithPermit\"\n        ) return _canDeposit(assets_);\n\n        return (false, \"PM:CC:INVALID_FUNCTION_ID\");\n    }\n\n    function factory() external view override returns (address factory_) {\n        factory_ = _factory();\n    }\n\n    function globals() public view override returns (address globals_) {\n        globals_ = IMapleProxyFactory(_factory()).mapleGlobals();\n    }\n\n    function governor() public view override returns (address governor_) {\n        governor_ = IGlobalsLike(globals()).governor();\n    }\n\n    function hasSufficientCover() public view override returns (bool hasSufficientCover_) {\n        hasSufficientCover_ = _hasSufficientCover(globals(), asset);\n    }\n\n    function implementation() external view override returns (address implementation_) {\n        implementation_ = _implementation();\n    }\n\n    function strategyListLength() external view override returns (uint256 strategyListLength_) {\n        strategyListLength_ = strategyList.length;\n    }\n\n    function totalAssets() public view override returns (uint256 totalAssets_) {\n        totalAssets_ = IERC20Like(asset).balanceOf(pool);\n\n        uint256 length_ = strategyList.length;\n\n        for (uint256 i_; i_ < length_;) {\n            totalAssets_ += IStrategyLike(strategyList[i_]).assetsUnderManagement();\n            unchecked { ++i_; }\n        }\n    }\n\n    /**************************************************************************************************************************************/\n    /*** LP Token View Functions                                                                                                        ***/\n    /**************************************************************************************************************************************/\n\n    function convertToExitShares(uint256 assets_) public view override returns (uint256 shares_) {\n        shares_ = IPoolLike(pool).convertToExitShares(assets_);\n    }\n\n    function getEscrowParams(address, uint256 shares_) external view override returns (uint256 escrowShares_, address destination_) {\n        // NOTE: `owner_` param not named to avoid compiler warning.\n        ( escrowShares_, destination_) = (shares_, address(this));\n    }\n\n    function maxDeposit(address receiver_) external view virtual override returns (uint256 maxAssets_) {\n        maxAssets_ = _getMaxAssets(receiver_, totalAssets(), \"P:deposit\");\n    }\n\n    function maxMint(address receiver_) external view virtual override returns (uint256 maxShares_) {\n        uint256 totalAssets_ = totalAssets();\n        uint256 maxAssets_   = _getMaxAssets(receiver_, totalAssets_, \"P:mint\");\n\n        maxShares_ = IPoolLike(pool).previewDeposit(maxAssets_);\n    }\n\n    function maxRedeem(address owner_) external view virtual override returns (uint256 maxShares_) {\n        uint256 lockedShares_ = IWithdrawalManagerLike(withdrawalManager).lockedShares(owner_);\n        maxShares_            = IWithdrawalManagerLike(withdrawalManager).isInExitWindow(owner_) ? lockedShares_ : 0;\n    }\n\n    function maxWithdraw(address owner_) external view virtual override returns (uint256 maxAssets_) {\n        owner_;          // Silence compiler warning\n        maxAssets_ = 0;  // NOTE: always returns 0 as withdraw is not implemented\n    }\n\n    function previewRedeem(address owner_, uint256 shares_) external view virtual override returns (uint256 assets_) {\n        ( , assets_ ) = IWithdrawalManagerLike(withdrawalManager).previewRedeem(owner_, shares_);\n    }\n\n    function previewWithdraw(address owner_, uint256 assets_) external view virtual override returns (uint256 shares_) {\n        ( , shares_ ) = IWithdrawalManagerLike(withdrawalManager).previewWithdraw(owner_, assets_);\n    }\n\n    function unrealizedLosses() public view override returns (uint256 unrealizedLosses_) {\n        uint256 length_ = strategyList.length;\n\n        for (uint256 i_; i_ < length_;) {\n            unrealizedLosses_ += IStrategyLike(strategyList[i_]).unrealizedLosses();\n            unchecked { ++i_; }\n        }\n\n        // NOTE: Use minimum to prevent underflows in the case that `unrealizedLosses` includes late interest and `totalAssets` does not.\n        unrealizedLosses_ = _min(unrealizedLosses_, totalAssets());\n    }\n\n    /**************************************************************************************************************************************/\n    /*** Internal Helper Functions                                                                                                      ***/\n    /**************************************************************************************************************************************/\n\n    function _getLoanManager(address loan_) internal view returns (address loanManager_) {\n        loanManager_ = ILoanLike(loan_).lender();\n\n        require(isStrategy[loanManager_], \"PM:GLM:INVALID_LOAN_MANAGER\");\n    }\n\n    function _handleCover(uint256 losses_, uint256 platformFees_) internal {\n        address globals_ = globals();\n\n        uint256 availableCover_ =\n            IERC20Like(asset).balanceOf(poolDelegateCover) * IGlobalsLike(globals_).maxCoverLiquidationPercent(address(this)) /\n            HUNDRED_PERCENT;\n\n        uint256 toTreasury_ = _min(availableCover_,               platformFees_);\n        uint256 toPool_     = _min(availableCover_ - toTreasury_, losses_);\n\n        if (toTreasury_ != 0) {\n            IPoolDelegateCoverLike(poolDelegateCover).moveFunds(toTreasury_, IGlobalsLike(globals_).mapleTreasury());\n        }\n\n        if (toPool_ != 0) {\n            IPoolDelegateCoverLike(poolDelegateCover).moveFunds(toPool_, pool);\n        }\n\n        emit CoverLiquidated(toTreasury_, toPool_);\n    }\n\n    /**************************************************************************************************************************************/\n    /*** Internal Functions                                                                                                             ***/\n    /**************************************************************************************************************************************/\n\n    function _address(uint256 word_) internal pure returns (address address_) {\n        address_ = address(uint160(word_));\n    }\n\n    function _canDeposit(uint256 assets_) internal view returns (bool canDeposit_, string memory errorMessage_) {\n        if (!active)                                return (false, \"P:NOT_ACTIVE\");\n        if (assets_ + totalAssets() > liquidityCap) return (false, \"P:DEPOSIT_GT_LIQ_CAP\");\n\n        return (true, \"\");\n    }\n\n    function _decodeParameters(bytes calldata data_) internal pure returns (uint256[3] memory words) {\n        if (data_.length > 64)  {\n            ( words[0], words[1], words[2] ) = abi.decode(data_, (uint256, uint256, uint256));\n        } else {\n            ( words[0], words[1] ) = abi.decode(data_, (uint256, uint256));\n        }\n    }\n\n    function _getMaxAssets(address receiver_, uint256 totalAssets_, bytes32 functionId_) internal view returns (uint256 maxAssets_) {\n        bool    depositAllowed_ = IPoolPermissionManagerLike(poolPermissionManager).hasPermission(address(this),  receiver_, functionId_);\n        uint256 liquidityCap_   = liquidityCap;\n        maxAssets_              = liquidityCap_ > totalAssets_ && depositAllowed_ ? liquidityCap_ - totalAssets_ : 0;\n    }\n\n    function _hasSufficientCover(address globals_, address asset_) internal view returns (bool hasSufficientCover_) {\n        hasSufficientCover_ = IERC20Like(asset_).balanceOf(poolDelegateCover) >= IGlobalsLike(globals_).minCoverAmount(address(this));\n    }\n\n    function _min(uint256 a_, uint256 b_) internal pure returns (uint256 minimum_) {\n        minimum_ = a_ < b_ ? a_ : b_;\n    }\n\n    function _revertIfConfigured() internal view {\n        require(!configured, \"PM:ALREADY_CONFIGURED\");\n    }\n\n    function _revertIfConfiguredAndNotProtocolAdmins() internal view {\n        require(\n            !configured ||\n            msg.sender == poolDelegate ||\n            msg.sender == governor()   ||\n            msg.sender == IGlobalsLike(globals()).operationalAdmin(),\n            \"PM:NOT_PA_OR_NOT_CONFIGURED\"\n        );\n    }\n\n    function _revertIfNotPool() internal view {\n        require(msg.sender == pool, \"PM:NOT_POOL\");\n    }\n\n    function _revertIfNotPoolDelegate() internal view {\n        require(msg.sender == poolDelegate, \"PM:NOT_PD\");\n    }\n\n    function _revertIfNeitherPoolDelegateNorProtocolAdmins() internal view {\n        require(\n            msg.sender == poolDelegate ||\n            msg.sender == governor()   ||\n            msg.sender == IGlobalsLike(globals()).operationalAdmin(),\n            \"PM:NOT_PD_OR_GOV_OR_OA\"\n        );\n    }\n\n    function _revertIfPaused() internal view {\n        require(!IGlobalsLike(globals()).isFunctionPaused(msg.sig), \"PM:PAUSED\");\n    }\n\n}\n"},"modules/erc20-helper/src/ERC20Helper.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.7;\n\nimport { IERC20Like } from \"./interfaces/IERC20Like.sol\";\n\n/**\n * @title Small Library to standardize erc20 token interactions.\n */\nlibrary ERC20Helper {\n\n    /**************************************************************************************************************************************/\n    /*** Internal Functions                                                                                                             ***/\n    /**************************************************************************************************************************************/\n\n    function transfer(address token_, address to_, uint256 amount_) internal returns (bool success_) {\n        return _call(token_, abi.encodeWithSelector(IERC20Like.transfer.selector, to_, amount_));\n    }\n\n    function transferFrom(address token_, address from_, address to_, uint256 amount_) internal returns (bool success_) {\n        return _call(token_, abi.encodeWithSelector(IERC20Like.transferFrom.selector, from_, to_, amount_));\n    }\n\n    function approve(address token_, address spender_, uint256 amount_) internal returns (bool success_) {\n        // If setting approval to zero fails, return false.\n        if (!_call(token_, abi.encodeWithSelector(IERC20Like.approve.selector, spender_, uint256(0)))) return false;\n\n        // If `amount_` is zero, return true as the previous step already did this.\n        if (amount_ == uint256(0)) return true;\n\n        // Return the result of setting the approval to `amount_`.\n        return _call(token_, abi.encodeWithSelector(IERC20Like.approve.selector, spender_, amount_));\n    }\n\n    function _call(address token_, bytes memory data_) private returns (bool success_) {\n        if (token_.code.length == uint256(0)) return false;\n\n        bytes memory returnData;\n        ( success_, returnData ) = token_.call(data_);\n\n        return success_ && (returnData.length == uint256(0) || abi.decode(returnData, (bool)));\n    }\n\n}\n"},"modules/maple-proxy-factory/contracts/interfaces/IMapleProxyFactory.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.7;\n\nimport { IDefaultImplementationBeacon } from \"../../modules/proxy-factory/contracts/interfaces/IDefaultImplementationBeacon.sol\";\n\n/// @title A Maple factory for Proxy contracts that proxy MapleProxied implementations.\ninterface IMapleProxyFactory is IDefaultImplementationBeacon {\n\n    /**************************************************************************************************************************************/\n    /*** Events                                                                                                                         ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev   A default version was set.\n     *  @param version_ The default version.\n     */\n    event DefaultVersionSet(uint256 indexed version_);\n\n    /**\n     *  @dev   A version of an implementation, at some address, was registered, with an optional initializer.\n     *  @param version_               The version registered.\n     *  @param implementationAddress_ The address of the implementation.\n     *  @param initializer_           The address of the initializer, if any.\n     */\n    event ImplementationRegistered(uint256 indexed version_, address indexed implementationAddress_, address indexed initializer_);\n\n    /**\n     *  @dev   A proxy contract was deployed with some initialization arguments.\n     *  @param version_                 The version of the implementation being proxied by the deployed proxy contract.\n     *  @param instance_                The address of the proxy contract deployed.\n     *  @param initializationArguments_ The arguments used to initialize the proxy contract, if any.\n     */\n    event InstanceDeployed(uint256 indexed version_, address indexed instance_, bytes initializationArguments_);\n\n    /**\n     *  @dev   A instance has upgraded by proxying to a new implementation, with some migration arguments.\n     *  @param instance_           The address of the proxy contract.\n     *  @param fromVersion_        The initial implementation version being proxied.\n     *  @param toVersion_          The new implementation version being proxied.\n     *  @param migrationArguments_ The arguments used to migrate, if any.\n     */\n    event InstanceUpgraded(address indexed instance_, uint256 indexed fromVersion_, uint256 indexed toVersion_, bytes migrationArguments_);\n\n    /**\n     *  @dev   The MapleGlobals was set.\n     *  @param mapleGlobals_ The address of a Maple Globals contract.\n     */\n    event MapleGlobalsSet(address indexed mapleGlobals_);\n\n    /**\n     *  @dev   An upgrade path was disabled, with an optional migrator contract.\n     *  @param fromVersion_ The starting version of the upgrade path.\n     *  @param toVersion_   The destination version of the upgrade path.\n     */\n    event UpgradePathDisabled(uint256 indexed fromVersion_, uint256 indexed toVersion_);\n\n    /**\n     *  @dev   An upgrade path was enabled, with an optional migrator contract.\n     *  @param fromVersion_ The starting version of the upgrade path.\n     *  @param toVersion_   The destination version of the upgrade path.\n     *  @param migrator_    The address of the migrator, if any.\n     */\n    event UpgradePathEnabled(uint256 indexed fromVersion_, uint256 indexed toVersion_, address indexed migrator_);\n\n    /**************************************************************************************************************************************/\n    /*** State Variables                                                                                                                ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev The default version.\n     */\n    function defaultVersion() external view returns (uint256 defaultVersion_);\n\n    /**\n     *  @dev The address of the MapleGlobals contract.\n     */\n    function mapleGlobals() external view returns (address mapleGlobals_);\n\n    /**\n     *  @dev    Whether the upgrade is enabled for a path from a version to another version.\n     *  @param  toVersion_   The initial version.\n     *  @param  fromVersion_ The destination version.\n     *  @return allowed_     Whether the upgrade is enabled.\n     */\n    function upgradeEnabledForPath(uint256 toVersion_, uint256 fromVersion_) external view returns (bool allowed_);\n\n    /**************************************************************************************************************************************/\n    /*** State Changing Functions                                                                                                       ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev    Deploys a new instance proxying the default implementation version, with some initialization arguments.\n     *          Uses a nonce and `msg.sender` as a salt for the CREATE2 opcode during instantiation to produce deterministic addresses.\n     *  @param  arguments_ The initialization arguments to use for the instance deployment, if any.\n     *  @param  salt_      The salt to use in the contract creation process.\n     *  @return instance_  The address of the deployed proxy contract.\n     */\n    function createInstance(bytes calldata arguments_, bytes32 salt_) external returns (address instance_);\n\n    /**\n     *  @dev   Enables upgrading from a version to a version of an implementation, with an optional migrator.\n     *         Only the Governor can call this function.\n     *  @param fromVersion_ The starting version of the upgrade path.\n     *  @param toVersion_   The destination version of the upgrade path.\n     *  @param migrator_    The address of the migrator, if any.\n     */\n    function enableUpgradePath(uint256 fromVersion_, uint256 toVersion_, address migrator_) external;\n\n    /**\n     *  @dev   Disables upgrading from a version to a version of a implementation.\n     *         Only the Governor can call this function.\n     *  @param fromVersion_ The starting version of the upgrade path.\n     *  @param toVersion_   The destination version of the upgrade path.\n     */\n    function disableUpgradePath(uint256 fromVersion_, uint256 toVersion_) external;\n\n    /**\n     *  @dev   Registers the address of an implementation contract as a version, with an optional initializer.\n     *         Only the Governor can call this function.\n     *  @param version_               The version to register.\n     *  @param implementationAddress_ The address of the implementation.\n     *  @param initializer_           The address of the initializer, if any.\n     */\n    function registerImplementation(uint256 version_, address implementationAddress_, address initializer_) external;\n\n    /**\n     *  @dev   Sets the default version.\n     *         Only the Governor can call this function.\n     *  @param version_ The implementation version to set as the default.\n     */\n    function setDefaultVersion(uint256 version_) external;\n\n    /**\n     *  @dev   Sets the Maple Globals contract.\n     *         Only the Governor can call this function.\n     *  @param mapleGlobals_ The address of a Maple Globals contract.\n     */\n    function setGlobals(address mapleGlobals_) external;\n\n    /**\n     *  @dev   Upgrades the calling proxy contract's implementation, with some migration arguments.\n     *  @param toVersion_ The implementation version to upgrade the proxy contract to.\n     *  @param arguments_ The migration arguments, if any.\n     */\n    function upgradeInstance(uint256 toVersion_, bytes calldata arguments_) external;\n\n    /**************************************************************************************************************************************/\n    /*** View Functions                                                                                                                 ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev    Returns the deterministic address of a potential proxy, given some arguments and salt.\n     *  @param  arguments_       The initialization arguments to be used when deploying the proxy.\n     *  @param  salt_            The salt to be used when deploying the proxy.\n     *  @return instanceAddress_ The deterministic address of a potential proxy.\n     */\n    function getInstanceAddress(bytes calldata arguments_, bytes32 salt_) external view returns (address instanceAddress_);\n\n    /**\n     *  @dev    Returns the address of an implementation version.\n     *  @param  version_        The implementation version.\n     *  @return implementation_ The address of the implementation.\n     */\n    function implementationOf(uint256 version_) external view returns (address implementation_);\n\n    /**\n     *  @dev    Returns if a given address has been deployed by this factory/\n     *  @param  instance_   The address to check.\n     *  @return isInstance_ A boolean indication if the address has been deployed by this factory.\n     */\n    function isInstance(address instance_) external view returns (bool isInstance_);\n\n    /**\n     *  @dev    Returns the address of a migrator contract for a migration path (from version, to version).\n     *          If oldVersion_ == newVersion_, the migrator is an initializer.\n     *  @param  oldVersion_ The old version.\n     *  @param  newVersion_ The new version.\n     *  @return migrator_   The address of a migrator contract.\n     */\n    function migratorForPath(uint256 oldVersion_, uint256 newVersion_) external view returns (address migrator_);\n\n    /**\n     *  @dev    Returns the version of an implementation contract.\n     *  @param  implementation_ The address of an implementation contract.\n     *  @return version_        The version of the implementation contract.\n     */\n    function versionOf(address implementation_) external view returns (uint256 version_);\n\n}\n"},"modules/maple-proxy-factory/contracts/interfaces/IMapleProxied.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.7;\n\nimport { IProxied } from \"../../modules/proxy-factory/contracts/interfaces/IProxied.sol\";\n\n/// @title A Maple implementation that is to be proxied, must implement IMapleProxied.\ninterface IMapleProxied is IProxied {\n\n    /**\n     *  @dev   The instance was upgraded.\n     *  @param toVersion_ The new version of the loan.\n     *  @param arguments_ The upgrade arguments, if any.\n     */\n    event Upgraded(uint256 toVersion_, bytes arguments_);\n\n    /**\n     *  @dev   Upgrades a contract implementation to a specific version.\n     *         Access control logic critical since caller can force a selfdestruct via a malicious `migrator_` which is delegatecalled.\n     *  @param toVersion_ The version to upgrade to.\n     *  @param arguments_ Some encoded arguments to use for the upgrade.\n     */\n    function upgrade(uint256 toVersion_, bytes calldata arguments_) external;\n\n}\n"},"modules/maple-proxy-factory/contracts/MapleProxiedInternals.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.7;\n\nimport { ProxiedInternals } from \"../modules/proxy-factory/contracts/ProxiedInternals.sol\";\n\n/// @title A Maple implementation that is to be proxied, will need MapleProxiedInternals.\nabstract contract MapleProxiedInternals is ProxiedInternals { }\n"},"contracts/proxy/MaplePoolManagerStorage.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.25;\n\nimport { IMaplePoolManagerStorage } from \"../interfaces/IMaplePoolManagerStorage.sol\";\n\nabstract contract MaplePoolManagerStorage is IMaplePoolManagerStorage {\n\n    uint256 internal _locked;  // Used when checking for reentrancy.\n\n    address public override poolDelegate;\n    address public override pendingPoolDelegate;\n\n    address public override asset;\n    address public override pool;\n\n    address public override poolDelegateCover;\n    address public override withdrawalManager;\n\n    bool public override active;\n    bool public override configured;\n    \n    bool __deprecated_openToPublic;\n\n    uint256 public override liquidityCap;\n    uint256 public override delegateManagementFeeRate;\n\n    mapping(address => bool) public override isStrategy;\n\n    mapping(address => bool) __deprecated_isValidLender;\n\n    address[] public override strategyList;\n\n    address public override poolPermissionManager;\n\n}\n"},"contracts/interfaces/Interfaces.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.7;\n\ninterface IERC20Like {\n\n    function allowance(address owner_, address spender_) external view returns (uint256 allowance_);\n\n    function balanceOf(address account_) external view returns (uint256 balance_);\n\n    function totalSupply() external view returns (uint256 totalSupply_);\n\n}\n\ninterface IGlobalsLike {\n\n    function bootstrapMint(address asset_) external view returns (uint256 bootstrapMint_);\n\n    function governor() external view returns (address governor_);\n\n    function isFunctionPaused(bytes4 sig_) external view returns (bool isFunctionPaused_);\n\n    function isInstanceOf(bytes32 instanceId_, address instance_) external view returns (bool isInstance_);\n\n    function isPoolAsset(address asset_) external view returns (bool isPoolAsset_);\n\n    function isPoolDelegate(address account_) external view returns (bool isPoolDelegate_);\n\n    function isPoolDeployer(address poolDeployer_) external view returns (bool isPoolDeployer_);\n\n    function isValidScheduledCall(address caller_, address contract_, bytes32 functionId_, bytes calldata callData_)\n        external view\n        returns (bool isValid_);\n\n    function mapleTreasury() external view returns (address mapleTreasury_);\n\n    function maxCoverLiquidationPercent(address poolManager_) external view returns (uint256 maxCoverLiquidationPercent_);\n\n    function migrationAdmin() external view returns (address migrationAdmin_);\n\n    function minCoverAmount(address poolManager_) external view returns (uint256 minCoverAmount_);\n\n    function operationalAdmin() external view returns (address operationalAdmin_);\n\n    function ownedPoolManager(address poolDelegate_) external view returns (address poolManager_);\n\n    function securityAdmin() external view returns (address securityAdmin_);\n\n    function transferOwnedPoolManager(address fromPoolDelegate_, address toPoolDelegate_) external;\n\n    function unscheduleCall(address caller_, bytes32 functionId_, bytes calldata callData_) external;\n\n}\n\ninterface IStrategyLike {\n\n    function assetsUnderManagement() external view returns (uint256 assetsUnderManagement_);\n\n    function unrealizedLosses() external view returns (uint256 unrealizedLosses_);\n\n}\n\ninterface ILoanManagerLike {\n\n    \n    function finishCollateralLiquidation(address loan_) external returns (uint256 remainingLosses_, uint256 serviceFee_);\n\n    function triggerDefault(address loan_, address liquidatorFactory_)\n        external\n        returns (bool liquidationComplete_, uint256 remainingLosses_, uint256 platformFees_);\n\n}\n\ninterface ILoanLike {\n\n    function lender() external view returns (address lender_);\n\n}\n\ninterface IMapleProxyFactoryLike {\n\n    function isInstance(address instance_) external view returns (bool isInstance_);\n\n    function mapleGlobals() external view returns (address mapleGlobals_);\n\n}\n\ninterface IPoolDelegateCoverLike {\n\n    function moveFunds(uint256 amount_, address recipient_) external;\n\n}\n\ninterface IPoolLike is IERC20Like {\n\n    function convertToExitShares(uint256 assets_) external view returns (uint256 shares_);\n\n    function previewDeposit(uint256 assets_) external view returns (uint256 shares_);\n\n    function previewMint(uint256 shares_) external view returns (uint256 assets_);\n\n}\n\ninterface IPoolManagerLike {\n\n    function addStrategy(address strategyFactory_, bytes calldata deploymentData_) external returns (address strategy_);\n\n    function canCall(bytes32 functionId_, address caller_, bytes memory data_)\n        external view\n        returns (bool canCall_, string memory errorMessage_);\n\n    function completeConfiguration() external;\n\n    function getEscrowParams(address owner_, uint256 shares_) external view returns (uint256 escrowShares_, address escrow_);\n\n    function maxDeposit(address receiver_) external view returns (uint256 maxAssets_);\n\n    function maxMint(address receiver_) external view returns (uint256 maxShares_);\n\n    function maxRedeem(address owner_) external view returns (uint256 maxShares_);\n\n    function maxWithdraw(address owner_) external view returns (uint256 maxAssets_);\n\n    function pool() external view returns (address pool_);\n\n    function poolDelegateCover() external view returns (address poolDelegateCover_);\n\n    function previewRedeem(address owner_, uint256 shares_) external view returns (uint256 assets_);\n\n    function previewWithdraw(address owner_, uint256 assets_) external view returns (uint256 shares_);\n\n    function processRedeem(uint256 shares_, address owner_, address sender_)\n        external\n        returns (uint256 redeemableShares_, uint256 resultingAssets_);\n\n    function processWithdraw(uint256 assets_, address owner_, address sender_)\n        external\n        returns (uint256 redeemableShares_, uint256 resultingAssets_);\n\n    function removeShares(uint256 shares_, address owner_) external returns (uint256 sharesReturned_);\n\n    function requestRedeem(uint256 shares_, address owner_, address sender_) external;\n\n    function requestWithdraw(uint256 shares_, uint256 assets_, address owner_, address sender_) external;\n\n    function setDelegateManagementFeeRate(uint256 delegateManagementFeeRate_) external;\n\n    function setLiquidityCap(uint256 liquidityCap_) external;\n\n    function setPoolPermissionManager(address poolPermissionManager_) external;\n\n    function setWithdrawalManager(address withdrawalManager_) external;\n\n    function totalAssets() external view returns (uint256 totalAssets_);\n\n    function unrealizedLosses() external view returns (uint256 unrealizedLosses_);\n\n}\n\ninterface IPoolPermissionManagerLike {\n\n    function hasPermission(address poolManager, address caller, bytes32 functionId) external view returns (bool allowed);\n\n    function hasPermission(address poolManager, address[] calldata caller, bytes32 functionId) external view returns (bool allowed);\n\n}\n\ninterface IWithdrawalManagerLike {\n\n    function addShares(uint256 shares_, address owner_) external;\n\n    function factory() external view returns (address factory_);\n\n    function isInExitWindow(address owner_) external view returns (bool isInExitWindow_);\n\n    function lockedLiquidity() external view returns (uint256 lockedLiquidity_);\n\n    function lockedShares(address owner_) external view returns (uint256 lockedShares_);\n\n    function previewRedeem(address owner_, uint256 shares) external view returns (uint256 redeemableShares, uint256 resultingAssets_);\n\n    function previewWithdraw(address owner_, uint256 assets_) external view returns (uint256 redeemableAssets_, uint256 resultingShares_);\n\n    function processExit(uint256 shares_, address account_) external returns (uint256 redeemableShares_, uint256 resultingAssets_);\n\n    function removeShares(uint256 shares_, address owner_) external returns (uint256 sharesReturned_);\n\n}\n"},"contracts/interfaces/IMaplePoolManager.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.7;\n\nimport { IMapleProxied } from \"../../modules/maple-proxy-factory/contracts/interfaces/IMapleProxied.sol\";\n\nimport { IMaplePoolManagerStorage } from \"./IMaplePoolManagerStorage.sol\";\n\ninterface IMaplePoolManager is IMapleProxied, IMaplePoolManagerStorage {\n\n    /**************************************************************************************************************************************/\n    /*** Events                                                                                                                         ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev   Emitted when a collateral liquidations is finished.\n     *  @param loan_             The address of the loan.\n     *  @param unrealizedLosses_ The amount of unrealized losses.\n     */\n    event CollateralLiquidationFinished(address indexed loan_, uint256 unrealizedLosses_);\n\n    /**\n     *  @dev   Emitted when a collateral liquidations is triggered.\n     *  @param loan_ The address of the loan.\n     */\n    event CollateralLiquidationTriggered(address indexed loan_);\n\n    /**\n     *  @dev   Emitted when cover is deposited.\n     *  @param amount_ The amount of cover deposited.\n     */\n    event CoverDeposited(uint256 amount_);\n\n    /**\n     *  @dev   Emitted when cover is liquidated in the case of a loan defaulting.\n     *  @param toTreasury_ The amount of cover sent to the Treasury.\n     *  @param toPool_     The amount of cover sent to the Pool.\n     */\n    event CoverLiquidated(uint256 toTreasury_, uint256 toPool_);\n\n    /**\n     *  @dev   Emitted when cover is withdrawn.\n     *  @param amount_ The amount of cover withdrawn.\n     */\n    event CoverWithdrawn(uint256 amount_);\n\n    /**\n     *  @dev   Emitted when a new management fee rate is set.\n     *  @param managementFeeRate_ The amount of management fee rate.\n     */\n    event DelegateManagementFeeRateSet(uint256 managementFeeRate_);\n\n    /**\n     *  @dev   Emitted when a strategy is set as valid.\n     *  @param strategy_   The address of the strategy.\n     *  @param isStrategy_ Whether the strategy is valid.\n     */\n    event IsStrategySet(address indexed strategy_, bool isStrategy_);\n\n    /**\n     *  @dev   Emitted when a new liquidity cap is set.\n     *  @param liquidityCap_ The value of liquidity cap.\n     */\n    event LiquidityCapSet(uint256 liquidityCap_);\n\n    /**\n     *  @dev   Emitted when a new strategy is added.\n     *  @param strategy_ The address of the new strategy.\n     */\n    event StrategyAdded(address indexed strategy_);\n\n    /**\n     *  @dev   Emitted when the pending pool delegate accepts the ownership transfer.\n     *  @param previousDelegate_ The address of the previous delegate.\n     *  @param newDelegate_      The address of the new delegate.\n     */\n    event PendingDelegateAccepted(address indexed previousDelegate_, address indexed newDelegate_);\n\n    /**\n     *  @dev   Emitted when the pending pool delegate is set.\n     *  @param previousDelegate_ The address of the previous delegate.\n     *  @param newDelegate_      The address of the new delegate.\n     */\n    event PendingDelegateSet(address indexed previousDelegate_, address indexed newDelegate_);\n\n    /**\n     *  @dev Emitted when the pool configuration is marked as complete.\n     */\n    event PoolConfigurationComplete();\n\n    /**\n     *  @dev   Emitted when the pool permission manager is set.\n     *  @param poolPermissionManager_ The address of the pool permission manager.\n     */\n    event PoolPermissionManagerSet(address indexed poolPermissionManager_);\n\n    /**\n     *  @dev   Emitted when a redemption of shares from the pool is processed.\n     *  @param owner_            The owner of the shares.\n     *  @param redeemableShares_ The amount of redeemable shares.\n     *  @param resultingAssets_  The amount of assets redeemed.\n     */\n    event RedeemProcessed(address indexed owner_, uint256 redeemableShares_, uint256 resultingAssets_);\n\n    /**\n     *  @dev   Emitted when a redemption of shares from the pool is requested.\n     *  @param owner_  The owner of the shares.\n     *  @param shares_ The amount of redeemable shares.\n     */\n    event RedeemRequested(address indexed owner_, uint256 shares_);\n\n    /**\n     *  @dev   Emitted when a pool is sets to be active or inactive.\n     *  @param active_ Whether the pool is active.\n     */\n    event SetAsActive(bool active_);\n\n    /**\n     *  @dev   Emitted when shares are removed from the pool.\n     *  @param owner_  The address of the owner of the shares.\n     *  @param shares_ The amount of shares removed.\n     */\n    event SharesRemoved(address indexed owner_, uint256 shares_);\n\n    /**\n     *  @dev   Emitted when the withdrawal manager is set.\n     *  @param withdrawalManager_ The address of the withdrawal manager.\n     */\n    event WithdrawalManagerSet(address indexed withdrawalManager_);\n\n    /**\n     *  @dev   Emitted when withdrawal of assets from the pool is processed.\n     *  @param owner_            The owner of the assets.\n     *  @param redeemableShares_ The amount of redeemable shares.\n     *  @param resultingAssets_  The amount of assets redeemed.\n     */\n    event WithdrawalProcessed(address indexed owner_, uint256 redeemableShares_, uint256 resultingAssets_);\n\n    /**************************************************************************************************************************************/\n    /*** Ownership Transfer Functions                                                                                                   ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev Accepts the role of pool delegate.\n     */\n    function acceptPoolDelegate() external;\n\n    /**\n     *  @dev   Sets an address as the pending pool delegate.\n     *  @param pendingPoolDelegate_ The address of the new pool delegate.\n     */\n    function setPendingPoolDelegate(address pendingPoolDelegate_) external;\n\n    /**************************************************************************************************************************************/\n    /*** Administrative Functions                                                                                                       ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev    Adds a new strategy.\n     *          NOTE: The PoolManager address is encoded and prepended to the extraDeploymentData.\n     *  @param  strategyFactory_     The address of the strategy factory to use.\n     *  @param  extraDeploymentData_ The data to construct the strategy.\n     *  @return strategy_            The address of the new strategy.\n     */\n    function addStrategy(address strategyFactory_, bytes calldata extraDeploymentData_) external returns (address strategy_);\n\n    /**\n     *  @dev Complete the configuration.\n     */\n    function completeConfiguration() external;\n\n    /**\n     *  @dev   Sets a the pool to be active or inactive.\n     *  @param active_ Whether the pool is active.\n     */\n    function setActive(bool active_) external;\n\n    /**\n     *  @dev   Sets the value for the delegate management fee rate.\n     *  @param delegateManagementFeeRate_ The value for the delegate management fee rate.\n     */\n    function setDelegateManagementFeeRate(uint256 delegateManagementFeeRate_) external;\n\n    /**\n     *  @dev   Sets if the strategy is valid in the isStrategy mapping.\n     *  @param strategy_   The address of the strategy\n     *  @param isStrategy_ Whether the strategy is valid.\n     */\n    function setIsStrategy(address strategy_, bool isStrategy_) external;\n\n    /**\n     *  @dev   Sets the value for liquidity cap.\n     *  @param liquidityCap_ The value for liquidity cap.\n     */\n    function setLiquidityCap(uint256 liquidityCap_) external;\n\n    /**\n     *  @dev   Sets the address of the pool permission manager.\n     *  @param poolPermission_ The address of the pool permission manager.\n     */\n    function setPoolPermissionManager(address poolPermission_) external;\n\n    /**\n     *  @dev   Sets the address of the withdrawal manager.\n     *  @param withdrawalManager_ The address of the withdrawal manager.\n     */\n    function setWithdrawalManager(address withdrawalManager_) external;\n\n    /**************************************************************************************************************************************/\n    /*** Funding Functions                                                                                                              ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev   Strategy can request funds from the pool via the poolManager.\n     *  @param destination_ The address to send the funds to.\n     *  @param principal_   The principal amount to fund the strategy with.\n     */\n    function requestFunds(address destination_, uint256 principal_) external;\n\n    /**************************************************************************************************************************************/\n    /*** Liquidation Functions                                                                                                          ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev   Finishes the collateral liquidation\n     *  @param loan_ Loan that had its collateral liquidated.\n     */\n    function finishCollateralLiquidation(address loan_) external;\n\n    /**\n     *  @dev   Triggers the default of a loan.\n     *  @param loan_              Loan to trigger the default.\n     *  @param liquidatorFactory_ Factory used to deploy the liquidator.\n     */\n    function triggerDefault(address loan_, address liquidatorFactory_) external;\n\n    /**************************************************************************************************************************************/\n    /*** Exit Functions                                                                                                                 ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev    Processes a redemptions of shares for assets from the pool.\n     *  @param  shares_           The amount of shares to redeem.\n     *  @param  owner_            The address of the owner of the shares.\n     *  @param  sender_           The address of the sender of the redeem call.\n     *  @return redeemableShares_ The amount of shares redeemed.\n     *  @return resultingAssets_  The amount of assets withdrawn.\n     */\n    function processRedeem(uint256 shares_, address owner_, address sender_)\n        external\n        returns (uint256 redeemableShares_, uint256 resultingAssets_);\n\n    /**\n     *  @dev    Processes a redemptions of shares for assets from the pool.\n     *  @param  assets_           The amount of assets to withdraw.\n     *  @param  owner_            The address of the owner of the shares.\n     *  @param  sender_           The address of the sender of the withdraw call.\n     *  @return redeemableShares_ The amount of shares redeemed.\n     *  @return resultingAssets_  The amount of assets withdrawn.\n     */\n    function processWithdraw(uint256 assets_, address owner_, address sender_)\n        external\n        returns (uint256 redeemableShares_, uint256 resultingAssets_);\n\n    /**\n     *  @dev    Requests a redemption of shares from the pool.\n     *  @param  shares_         The amount of shares to redeem.\n     *  @param  owner_          The address of the owner of the shares.\n     *  @return sharesReturned_ The amount of shares withdrawn.\n     */\n    function removeShares(uint256 shares_, address owner_) external returns (uint256 sharesReturned_);\n\n    /**\n     *  @dev   Requests a redemption of shares from the pool.\n     *  @param shares_ The amount of shares to redeem.\n     *  @param owner_  The address of the owner of the shares.\n     *  @param sender_ The address of the sender of the shares.\n     */\n    function requestRedeem(uint256 shares_, address owner_, address sender_) external;\n\n    /**\n     *  @dev   Requests a withdrawal of assets from the pool.\n     *  @param shares_ The amount of shares to redeem.\n     *  @param assets_ The amount of assets to withdraw.\n     *  @param owner_  The address of the owner of the shares.\n     *  @param sender_ The address of the sender of the shares.\n     */\n     function requestWithdraw(uint256 shares_, uint256 assets_, address owner_, address sender_) external;\n\n    /**************************************************************************************************************************************/\n    /*** Cover Functions                                                                                                                ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev   Deposits cover into the pool.\n     *  @param amount_ The amount of cover to deposit.\n     */\n    function depositCover(uint256 amount_) external;\n\n    /**\n     *  @dev   Withdraws cover from the pool.\n     *  @param amount_    The amount of cover to withdraw.\n     *  @param recipient_ The address of the recipient.\n     */\n    function withdrawCover(uint256 amount_, address recipient_) external;\n\n    /**************************************************************************************************************************************/\n    /*** LP Token View Functions                                                                                                        ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev    Returns the amount of exit shares for the input amount.\n     *  @param  amount_  Address of the account.\n     *  @return shares_  Amount of shares able to be exited.\n     */\n    function convertToExitShares(uint256 amount_) external view returns (uint256 shares_);\n\n    /**\n     *  @dev    Gets the information of escrowed shares.\n     *  @param  owner_        The address of the owner of the shares.\n     *  @param  shares_       The amount of shares to get the information of.\n     *  @return escrowShares_ The amount of escrowed shares.\n     *  @return destination_  The address of the destination.\n     */\n    function getEscrowParams(address owner_, uint256 shares_) external view returns (uint256 escrowShares_, address destination_);\n\n    /**\n     *  @dev   Gets the amount of assets that can be deposited.\n     *  @param receiver_  The address to check the deposit for.\n     *  @param maxAssets_ The maximum amount assets to deposit.\n     */\n    function maxDeposit(address receiver_) external view returns (uint256 maxAssets_);\n\n    /**\n     *  @dev   Gets the amount of shares that can be minted.\n     *  @param receiver_  The address to check the mint for.\n     *  @param maxShares_ The maximum amount shares to mint.\n     */\n    function maxMint(address receiver_) external view returns (uint256 maxShares_);\n\n    /**\n     *  @dev   Gets the amount of shares that can be redeemed.\n     *  @param owner_     The address to check the redemption for.\n     *  @param maxShares_ The maximum amount shares to redeem.\n     */\n    function maxRedeem(address owner_) external view returns (uint256 maxShares_);\n\n    /**\n     *  @dev   Gets the amount of assets that can be withdrawn.\n     *  @param owner_     The address to check the withdraw for.\n     *  @param maxAssets_ The maximum amount assets to withdraw.\n     */\n    function maxWithdraw(address owner_) external view returns (uint256 maxAssets_);\n\n    /**\n     *  @dev    Gets the amount of shares that can be redeemed.\n     *  @param  owner_   The address to check the redemption for.\n     *  @param  shares_  The amount of requested shares to redeem.\n     *  @return assets_  The amount of assets that will be returned for `shares_`.\n     */\n    function previewRedeem(address owner_, uint256 shares_) external view returns (uint256 assets_);\n\n    /**\n     *  @dev    Gets the amount of assets that can be redeemed.\n     *  @param  owner_   The address to check the redemption for.\n     *  @param  assets_  The amount of requested shares to redeem.\n     *  @return shares_  The amount of assets that will be returned for `assets_`.\n     */\n    function previewWithdraw(address owner_, uint256 assets_) external view returns (uint256 shares_);\n\n    /**************************************************************************************************************************************/\n    /*** View Functions                                                                                                                 ***/\n    /**************************************************************************************************************************************/\n\n    /**\n     *  @dev    Checks if a scheduled call can be executed.\n     *  @param  functionId_   The function to check.\n     *  @param  caller_       The address of the caller.\n     *  @param  data_         The data of the call.\n     *  @return canCall_      True if the call can be executed, false otherwise.\n     *  @return errorMessage_ The error message if the call cannot be executed.\n     */\n    function canCall(bytes32 functionId_, address caller_, bytes memory data_)\n        external view\n        returns (bool canCall_, string memory errorMessage_);\n\n    /**\n     *  @dev    Gets the address of the globals.\n     *  @return globals_ The address of the globals.\n     */\n    function globals() external view returns (address globals_);\n\n    /**\n     *  @dev    Gets the address of the governor.\n     *  @return governor_ The address of the governor.\n     */\n    function governor() external view returns (address governor_);\n\n    /**\n     *  @dev    Returns if pool has sufficient cover.\n     *  @return hasSufficientCover_ True if pool has sufficient cover.\n     */\n    function hasSufficientCover() external view returns (bool hasSufficientCover_);\n\n    /**\n     *  @dev    Returns the length of the `strategyList`.\n     *  @return strategyListLength_ The length of the `strategyList`.\n     */\n    function strategyListLength() external view returns (uint256 strategyListLength_);\n\n    /**\n     *  @dev    Returns the amount of total assets.\n     *  @return totalAssets_ Amount of of total assets.\n     */\n    function totalAssets() external view returns (uint256 totalAssets_);\n\n    /**\n     *  @dev    Returns the amount unrealized losses.\n     *  @return unrealizedLosses_ Amount of unrealized losses.\n     */\n    function unrealizedLosses() external view returns (uint256 unrealizedLosses_);\n\n}\n"},"modules/erc20-helper/src/interfaces/IERC20Like.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.7;\n\n/// @title Interface of the ERC20 standard as needed by ERC20Helper.\ninterface IERC20Like {\n\n    function approve(address spender_, uint256 amount_) external returns (bool success_);\n\n    function transfer(address recipient_, uint256 amount_) external returns (bool success_);\n\n    function transferFrom(address owner_, address recipient_, uint256 amount_) external returns (bool success_);\n\n}\n"},"modules/maple-proxy-factory/modules/proxy-factory/contracts/interfaces/IDefaultImplementationBeacon.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.7;\n\n/// @title An beacon that provides a default implementation for proxies, must implement IDefaultImplementationBeacon.\ninterface IDefaultImplementationBeacon {\n\n    /// @dev The address of an implementation for proxies.\n    function defaultImplementation() external view returns (address defaultImplementation_);\n\n}\n"},"modules/maple-proxy-factory/modules/proxy-factory/contracts/interfaces/IProxied.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.7;\n\n/// @title An implementation that is to be proxied, must implement IProxied.\ninterface IProxied {\n\n    /**\n     *  @dev The address of the proxy factory.\n     */\n    function factory() external view returns (address factory_);\n\n    /**\n     *  @dev The address of the implementation contract being proxied.\n     */\n    function implementation() external view returns (address implementation_);\n\n    /**\n     *  @dev   Modifies the proxy's implementation address.\n     *  @param newImplementation_ The address of an implementation contract.\n     */\n    function setImplementation(address newImplementation_) external;\n\n    /**\n     *  @dev   Modifies the proxy's storage by delegate-calling a migrator contract with some arguments.\n     *         Access control logic critical since caller can force a selfdestruct via a malicious `migrator_` which is delegatecalled.\n     *  @param migrator_  The address of a migrator contract.\n     *  @param arguments_ Some encoded arguments to use for the migration.\n     */\n    function migrate(address migrator_, bytes calldata arguments_) external;\n\n}\n"},"modules/maple-proxy-factory/modules/proxy-factory/contracts/ProxiedInternals.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.7;\n\nimport { SlotManipulatable } from \"./SlotManipulatable.sol\";\n\n/// @title An implementation that is to be proxied, will need ProxiedInternals.\nabstract contract ProxiedInternals is SlotManipulatable {\n\n    /// @dev Storage slot with the address of the current factory. `keccak256('eip1967.proxy.factory') - 1`.\n    bytes32 private constant FACTORY_SLOT = bytes32(0x7a45a402e4cb6e08ebc196f20f66d5d30e67285a2a8aa80503fa409e727a4af1);\n\n    /// @dev Storage slot with the address of the current factory. `keccak256('eip1967.proxy.implementation') - 1`.\n    bytes32 private constant IMPLEMENTATION_SLOT = bytes32(0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc);\n\n    /// @dev Delegatecalls to a migrator contract to manipulate storage during an initialization or migration.\n    function _migrate(address migrator_, bytes calldata arguments_) internal virtual returns (bool success_) {\n        uint256 size;\n\n        assembly {\n            size := extcodesize(migrator_)\n        }\n\n        if (size == uint256(0)) return false;\n\n        ( success_, ) = migrator_.delegatecall(arguments_);\n    }\n\n    /// @dev Sets the factory address in storage.\n    function _setFactory(address factory_) internal virtual returns (bool success_) {\n        _setSlotValue(FACTORY_SLOT, bytes32(uint256(uint160(factory_))));\n        return true;\n    }\n\n    /// @dev Sets the implementation address in storage.\n    function _setImplementation(address implementation_) internal virtual returns (bool success_) {\n        _setSlotValue(IMPLEMENTATION_SLOT, bytes32(uint256(uint160(implementation_))));\n        return true;\n    }\n\n    /// @dev Returns the factory address.\n    function _factory() internal view virtual returns (address factory_) {\n        return address(uint160(uint256(_getSlotValue(FACTORY_SLOT))));\n    }\n\n    /// @dev Returns the implementation address.\n    function _implementation() internal view virtual returns (address implementation_) {\n        return address(uint160(uint256(_getSlotValue(IMPLEMENTATION_SLOT))));\n    }\n\n}\n"},"contracts/interfaces/IMaplePoolManagerStorage.sol":{"content":"// SPDX-License-Identifier: BUSL-1.1\npragma solidity ^0.8.7;\n\ninterface IMaplePoolManagerStorage {\n\n    /**\n     *  @dev    Returns whether or not a pool is active.\n     *  @return active_ True if the pool is active.\n     */\n    function active() external view returns (bool active_);\n\n    /**\n     *  @dev    Gets the address of the funds asset.\n     *  @return asset_ The address of the funds asset.\n     */\n    function asset() external view returns (address asset_);\n\n    /**\n     *  @dev    Returns whether or not a pool is configured.\n     *  @return configured_ True if the pool is configured.\n     */\n    function configured() external view returns (bool configured_);\n\n    /**\n     *  @dev    Gets the delegate management fee rate.\n     *  @return delegateManagementFeeRate_ The value for the delegate management fee rate.\n     */\n    function delegateManagementFeeRate() external view returns (uint256 delegateManagementFeeRate_);\n\n    /**\n     *  @dev    Returns whether or not the given address is a strategy.\n     *  @param  strategy_   The address of the strategy.\n     *  @return isStrategy_ True if the address is a strategy.\n     */\n    function isStrategy(address strategy_) external view returns (bool isStrategy_);\n\n    /**\n     *  @dev    Gets the liquidity cap for the pool.\n     *  @return liquidityCap_ The liquidity cap for the pool.\n     */\n    function liquidityCap() external view returns (uint256 liquidityCap_);\n\n    /**\n     *  @dev    Gets the address of the strategy in the list.\n     *  @param  index_    The index to get the address of.\n     *  @return strategy_ The address in the list.\n     */\n    function strategyList(uint256 index_) external view returns (address strategy_);\n\n    /**\n     *  @dev    Gets the address of the pending pool delegate.\n     *  @return pendingPoolDelegate_ The address of the pending pool delegate.\n     */\n    function pendingPoolDelegate() external view returns (address pendingPoolDelegate_);\n\n    /**\n     *  @dev    Gets the address of the pool.\n     *  @return pool_ The address of the pool.\n     */\n    function pool() external view returns (address pool_);\n\n    /**\n     *  @dev    Gets the address of the pool delegate.\n     *  @return poolDelegate_ The address of the pool delegate.\n     */\n    function poolDelegate() external view returns (address poolDelegate_);\n\n    /**\n     *  @dev    Gets the address of the pool delegate cover.\n     *  @return poolDelegateCover_ The address of the pool delegate cover.\n     */\n    function poolDelegateCover() external view returns (address poolDelegateCover_);\n\n    /**\n     *  @dev    Gets the address of the pool delegate cover.\n     *  @return poolPermissionManager_ The address of the pool permission manager.\n     */\n    function poolPermissionManager() external view returns (address poolPermissionManager_);\n\n    /**\n     *  @dev    Gets the address of the withdrawal manager.\n     *  @return withdrawalManager_ The address of the withdrawal manager.\n     */\n    function withdrawalManager() external view returns (address withdrawalManager_);\n\n}\n"},"modules/maple-proxy-factory/modules/proxy-factory/contracts/SlotManipulatable.sol":{"content":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity ^0.8.7;\n\nabstract contract SlotManipulatable {\n\n    function _getReferenceTypeSlot(bytes32 slot_, bytes32 key_) internal pure returns (bytes32 value_) {\n        return keccak256(abi.encodePacked(key_, slot_));\n    }\n\n    function _getSlotValue(bytes32 slot_) internal view returns (bytes32 value_) {\n        assembly {\n            value_ := sload(slot_)\n        }\n    }\n\n    function _setSlotValue(bytes32 slot_, bytes32 value_) internal {\n        assembly {\n            sstore(slot_, value_)\n        }\n    }\n\n}\n"}},"matchId":"6330880","creationMatch":"match","runtimeMatch":"match","verifiedAt":"2025-05-01T19:59:48Z","match":"match","chainId":"1","address":"0xfE02Be1aD28EdFd8e3dD6F29C402B244C2A258B8"}