creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/actions/common/Executable.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\n/**\n * @title Shared Action Executable interface\n * @notice Provides a dma-common interface for an execute method to all Action\n */\ninterface Executable {\n  function execute(bytes calldata data, uint8[] memory paramsMap) external payable;\n}\n"
      },
      "contracts/actions/morpho-blue/Borrow.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\nimport { Executable } from \"../common/Executable.sol\";\nimport { UseStorageSlot, StorageSlot, Write, Read } from \"../../libs/UseStorageSlot.sol\";\nimport { ServiceRegistry } from \"../../core/ServiceRegistry.sol\";\nimport { BorrowData } from \"../../core/types/MorphoBlue.sol\";\nimport { MORPHO_BLUE } from \"../../core/constants/MorphoBlue.sol\";\nimport { IMorpho } from \"../../interfaces/morpho-blue/IMorpho.sol\";\nimport { UseRegistry } from \"../../libs/UseRegistry.sol\";\n\n/**\n * @title Borrow | Morpho Blue Action contract\n * @notice Borrows token from MorphoBlue's lending pool\n */\ncontract MorphoBlueBorrow is Executable, UseStorageSlot, UseRegistry {\n  using Write for StorageSlot.TransactionStorage;\n\n  constructor(address _registry) UseRegistry(ServiceRegistry(_registry)) {}\n\n  /**\n   * @param data Encoded calldata that conforms to the BorrowData struct\n   */\n  function execute(bytes calldata data, uint8[] memory) external payable override {\n    BorrowData memory borrowData = parseInputs(data);\n\n    IMorpho morphoBlue = IMorpho(getRegisteredService(MORPHO_BLUE));\n    morphoBlue.borrow(borrowData.marketParams, borrowData.amount, 0, address(this), address(this));\n\n    store().write(bytes32(borrowData.amount));\n  }\n\n  function parseInputs(bytes memory _callData) public pure returns (BorrowData memory params) {\n    return abi.decode(_callData, (BorrowData));\n  }\n}\n"
      },
      "contracts/core/constants/Common.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\nstring constant OPERATION_STORAGE = \"OperationStorage_5\";\nstring constant OPERATION_EXECUTOR = \"OperationExecutor_5\";\nstring constant OPERATIONS_REGISTRY = \"OperationsRegistry_5\";\nstring constant CHAINLOG_VIEWER = \"ChainLogView\";\nstring constant ONE_INCH_AGGREGATOR = \"OneInchAggregator\";\nstring constant ONE_INCH_AGGREGATOR5 = \"OneInchAggregator5\";\nstring constant DS_GUARD_FACTORY = \"DSGuardFactory\";\nstring constant WETH = \"WETH\";\nstring constant DAI = \"DAI\";\nuint256 constant RAY = 10 ** 27;\nbytes32 constant NULL = \"\";\n\n/**\n * @dev We do not include patch versions in contract names to allow\n * for hotfixes of Action dma-contracts\n * and to limit updates to TheGraph\n * if the types encoded in emitted events change then use a minor version and\n * update the ServiceRegistry with a new entry\n * and update TheGraph decoding accordingly\n */\nstring constant POSITION_CREATED_ACTION = \"PositionCreated\";\n\nstring constant UNISWAP_ROUTER = \"UniswapRouter\";\nstring constant SWAP = \"Swap_2\";\n\naddress constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;\n"
      },
      "contracts/core/constants/MorphoBlue.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\nstring constant MORPHO_BLUE = \"MorphoBlue\";\n"
      },
      "contracts/core/OperationStorage.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\nimport { ServiceRegistry } from \"./ServiceRegistry.sol\";\n\n/**\n * @title Operation Storage\n * @notice Stores the return values from Actions during an Operation's execution\n * @dev valuesHolders is an array of t/x initiators (msg.sender) who have pushed values to Operation Storage\n * returnValues is a mapping between a msg.sender and an array of Action return values generated by that senders transaction\n */\ncontract OperationStorage {\n  uint8 internal action = 0;\n  bytes32[] public actions;\n  bool[] public optionals;\n  mapping(address => bytes32[]) public returnValues;\n  address[] public valuesHolders;\n  bool private locked;\n  address private whoLocked;\n  address public initiator;\n  address immutable operationExecutorAddress;\n\n  ServiceRegistry internal immutable registry;\n\n  constructor(ServiceRegistry _registry, address _operationExecutorAddress) {\n    registry = _registry;\n    operationExecutorAddress = _operationExecutorAddress;\n  }\n\n  /**\n   * @dev Locks storage to protect against re-entrancy attacks.@author\n   */\n  function lock() external {\n    locked = true;\n    whoLocked = msg.sender;\n  }\n\n  /**\n   * @dev Only the original locker can unlock the contract at the end of the transaction\n   */\n  function unlock() external {\n    require(whoLocked == msg.sender, \"Only the locker can unlock\");\n    require(locked, \"Not locked\");\n    locked = false;\n    whoLocked = address(0);\n  }\n\n  /**\n   * @dev Sets the initiator of the original call\n   * Is used by Automation Bot branch in the onFlashloan callback in Operation Executor\n   * Ensures that third party calls to Operation Storage do not maliciously override values in Operation Storage\n   * @param _initiator Sets the initiator to Operation Executor contract when storing return values from flashloan nested Action\n   */\n  function setInitiator(address _initiator) external {\n    require(msg.sender == operationExecutorAddress);\n    initiator = _initiator;\n  }\n\n  /**\n   * @param _actions Stores the Actions currently being executed for a given Operation and their optionality\n   */\n  function setOperationActions(bytes32[] memory _actions, bool[] memory _optionals) external {\n    actions = _actions;\n    optionals = _optionals;\n  }\n\n  /**\n   * @param actionHash Checks the current action has against the expected action hash\n   */\n  function verifyAction(bytes32 actionHash, bool skipped) external {\n    if (skipped) {\n      require(optionals[action], \"Action cannot be skipped\");\n    }\n    require(actions[action] == actionHash, \"incorrect-action\");\n    registry.getServiceAddress(actionHash);\n    action++;\n  }\n\n  /**\n   * @dev Custom operations have no Actions stored in Operation Registry\n   * @return Returns true / false depending on whether the Operation has any actions to verify the Operation against\n   */\n  function hasActionsToVerify() external view returns (bool) {\n    return actions.length > 0;\n  }\n\n  /**\n   * @param value Pushes a bytes32 to end of the returnValues array\n   */\n  function push(bytes32 value) external {\n    address who = msg.sender;\n    if (who == operationExecutorAddress) {\n      who = initiator;\n    }\n\n    if (returnValues[who].length == 0) {\n      valuesHolders.push(who);\n    }\n    returnValues[who].push(value);\n  }\n\n  /**\n   * @dev Values are stored against an address (who)\n   * This ensures that malicious actors looking to push values to Operation Storage mid transaction cannot overwrite values\n   * @param index The index of the desired value\n   * @param who The msg.sender address responsible for storing values\n   */\n  function at(uint256 index, address who) external view returns (bytes32) {\n    if (who == operationExecutorAddress) {\n      who = initiator;\n    }\n    return returnValues[who][index];\n  }\n\n  /**\n   * @param who The msg.sender address responsible for storing values\n   * @return The length of return values stored against a given msg.sender address\n   */\n  function len(address who) external view returns (uint256) {\n    if (who == operationExecutorAddress) {\n      who = initiator;\n    }\n    return returnValues[who].length;\n  }\n\n  /**\n   * @dev Clears storage in preparation for the next Operation\n   */\n  function clearStorage() external {\n    delete action;\n    delete actions;\n    for (uint256 i = 0; i < valuesHolders.length; i++) {\n      delete returnValues[valuesHolders[i]];\n    }\n    delete valuesHolders;\n  }\n}\n"
      },
      "contracts/core/ServiceRegistry.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\n\n/// ServiceRegistry.sol\n\n// Copyright (C) 2021-2021 Oazo Apps Limited\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program.  If not, see <https://www.gnu.org/licenses/>.\npragma solidity ^0.8.0;\n\ncontract ServiceRegistry {\n  uint256 public constant MAX_DELAY = 30 days;\n\n  mapping(bytes32 => uint256) public lastExecuted;\n  mapping(bytes32 => address) private namedService;\n  mapping(bytes32 => bool) private invalidHashes;\n  address public owner;\n  uint256 public requiredDelay;\n\n  modifier validateInput(uint256 len) {\n    require(msg.data.length == len, \"registry/illegal-padding\");\n    _;\n  }\n\n  modifier delayedExecution() {\n    bytes32 operationHash = keccak256(msg.data);\n    uint256 reqDelay = requiredDelay;\n\n    /* solhint-disable not-rely-on-time */\n    if (lastExecuted[operationHash] == 0 && reqDelay > 0) {\n      // not called before, scheduled for execution\n      lastExecuted[operationHash] = block.timestamp;\n      emit ChangeScheduled(operationHash, block.timestamp + reqDelay, msg.data);\n    } else {\n      require(block.timestamp - reqDelay > lastExecuted[operationHash], \"registry/delay-too-small\");\n      emit ChangeApplied(operationHash, block.timestamp, msg.data);\n      _;\n      lastExecuted[operationHash] = 0;\n    }\n    /* solhint-enable not-rely-on-time */\n  }\n\n  modifier onlyOwner() {\n    require(msg.sender == owner, \"registry/only-owner\");\n    _;\n  }\n\n  constructor(uint256 initialDelay) {\n    require(initialDelay <= MAX_DELAY, \"registry/invalid-delay\");\n    requiredDelay = initialDelay;\n    owner = msg.sender;\n  }\n\n  function transferOwnership(\n    address newOwner\n  ) external onlyOwner validateInput(36) delayedExecution {\n    owner = newOwner;\n  }\n\n  function changeRequiredDelay(\n    uint256 newDelay\n  ) external onlyOwner validateInput(36) delayedExecution {\n    require(newDelay <= MAX_DELAY, \"registry/invalid-delay\");\n    requiredDelay = newDelay;\n  }\n\n  function getServiceNameHash(string memory name) external pure returns (bytes32) {\n    return keccak256(abi.encodePacked(name));\n  }\n\n  function addNamedService(\n    bytes32 serviceNameHash,\n    address serviceAddress\n  ) external onlyOwner validateInput(68) delayedExecution {\n    require(invalidHashes[serviceNameHash] == false, \"registry/service-name-used-before\");\n    require(namedService[serviceNameHash] == address(0), \"registry/service-override\");\n    namedService[serviceNameHash] = serviceAddress;\n    emit NamedServiceAdded(serviceNameHash, serviceAddress);\n  }\n\n  function removeNamedService(bytes32 serviceNameHash) external onlyOwner validateInput(36) {\n    require(namedService[serviceNameHash] != address(0), \"registry/service-does-not-exist\");\n    namedService[serviceNameHash] = address(0);\n    invalidHashes[serviceNameHash] = true;\n    emit NamedServiceRemoved(serviceNameHash);\n  }\n\n  function getRegisteredService(string memory serviceName) external view returns (address) {\n    return namedService[keccak256(abi.encodePacked(serviceName))];\n  }\n\n  function getServiceAddress(bytes32 serviceNameHash) external view returns (address) {\n    return namedService[serviceNameHash];\n  }\n\n  function clearScheduledExecution(\n    bytes32 scheduledExecution\n  ) external onlyOwner validateInput(36) {\n    require(lastExecuted[scheduledExecution] > 0, \"registry/execution-not-scheduled\");\n    lastExecuted[scheduledExecution] = 0;\n    emit ChangeCancelled(scheduledExecution);\n  }\n\n  event ChangeScheduled(bytes32 dataHash, uint256 scheduledFor, bytes data);\n  event ChangeApplied(bytes32 dataHash, uint256 appliedAt, bytes data);\n  event ChangeCancelled(bytes32 dataHash);\n  event NamedServiceRemoved(bytes32 nameHash);\n  event NamedServiceAdded(bytes32 nameHash, address service);\n}\n"
      },
      "contracts/core/types/MorphoBlue.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\nimport { MarketParams } from \"../../interfaces/morpho-blue/IMorpho.sol\";\n\nstruct DepositData {\n  MarketParams marketParams;\n  uint256 amount;\n  bool sumAmounts;\n}\n\nstruct BorrowData {\n  MarketParams marketParams;\n  uint256 amount;\n}\n\nstruct WithdrawData {\n  MarketParams marketParams;\n  uint256 amount;\n  address to;\n}\n\nstruct PaybackData {\n  MarketParams marketParams;\n  uint256 amount;\n  address onBehalf;\n  bool paybackAll;\n}\n"
      },
      "contracts/interfaces/morpho-blue/IMorpho.sol": {
        "content": "// SPDX-License-Identifier: GPL-2.0-or-later\npragma solidity >=0.5.0;\n\ntype Id is bytes32;\n\n  struct 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.\n  struct 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.\n  struct Market {\n    uint128 totalSupplyAssets;\n    uint128 totalSupplyShares;\n    uint128 totalBorrowAssets;\n    uint128 totalBorrowShares;\n    uint128 lastUpdate;\n    uint128 fee;\n  }\n\n  struct Authorization {\n    address authorizer;\n    address authorized;\n    bool isAuthorized;\n    uint256 nonce;\n    uint256 deadline;\n  }\n\n  struct 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 another chain sharing\n  /// the same chain id 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  /// @dev Here is a list of properties on the market's dependencies that could break Morpho's liveness properties\n  /// (funds could get stuck):\n  /// - The token can revert on `transfer` and `transferFrom` for a reason other than an approval or balance issue.\n  /// - A very high amount of assets (~1e35) supplied or borrowed can make the computation of `toSharesUp` and\n  /// `toSharesDown` overflow.\n  /// - The IRM can revert on `borrowRate`.\n  /// - A very high borrow rate returned by the IRM can make the computation of `interest` in `_accrueInterest`\n  /// overflow.\n  /// - The oracle can revert on `price`. Note that this can be used to prevent `borrow`, `withdrawCollateral` and\n  /// `liquidate` from being used under certain market conditions.\n  /// - A very high price returned by the oracle can make the computation of `maxBorrow` in `_isHealthy` overflow, or\n  /// the computation of `assetsRepaid` in `liquidate` 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  /// `onMorphoReplay` 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(\n    MarketParams memory marketParams,\n    uint256 assets,\n    address onBehalf,\n    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(\n    MarketParams memory marketParams,\n    uint256 assets,\n    address onBehalf,\n    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(\n    Authorization calldata authorization,\n    Signature calldata signature\n  ) 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(\n    Id id,\n    address user\n  ) external view 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(\n    Id id\n  )\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(\n    Id id\n  )\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"
      },
      "contracts/libs/UseRegistry.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\nimport { OperationStorage } from \"../core/OperationStorage.sol\";\nimport { ServiceRegistry } from \"../core/ServiceRegistry.sol\";\nimport { OPERATION_STORAGE } from \"../core/constants/Common.sol\";\n\n/**\n * @title UseRegistry contract\n * @notice Provides common interface for all Actions to access the ServiceRegistry contract\n */\n\ncontract UseRegistry { \n  ServiceRegistry private immutable _registry;\n  constructor(ServiceRegistry registry_) {\n    _registry = registry_;\n  } \n\n  function getRegisteredService(string memory service) internal view returns (address) {\n    return _registry.getRegisteredService(service); \n  }\n}\n"
      },
      "contracts/libs/UseStorageSlot.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0-or-later\npragma solidity ^0.8.15;\n\n/**\n * @title A library that operates on a storage slot\n * @notice It is used to storage all kind of information that is going to be used during a transaction life time.\n * @dev The system of contracts that utilize this library work under the assumption\n * that all contracts are called in the scope of a proxy. Using the library will create a storage pointer\n * to a slot in the Proxy instance.\n * The `TransactionStorage` structure contains the following properties:\n *  - actions - Each executed action's hash is pushed into the array. At the end of the operation execution,\n * this values are concatenated ( abi.encodePacked ) .\n *  - returnedValues - Used to store values from actions. It is used to share values between actions and\n * other interested contacts\n */\nlibrary StorageSlot {\n  struct TransactionStorage {\n    bytes32[] actions;\n    bytes32[] returnedValues;\n  }\n\n  /**\n   * @notice Used to get a storage slot at a specific slot position\n   */\n  function getTransactionStorage() internal pure returns (TransactionStorage storage tStorage) {\n    bytes32 slotPosition = bytes32(uint256(keccak256(\"proxy.transaction.storage\")) - 1);\n\n    assembly {\n      tStorage.slot := slotPosition\n    }\n  }\n}\n\n/**\n * @title Used to read from the StorageSlot\n * @notice There is a structure used in the StorageSlot library that is used\n * to create a storage pointer. This library read from a specific property of that structure.\n * It is used to read a specific returned value from an Action.\n */\nlibrary Read {\n  function read(\n    StorageSlot.TransactionStorage storage _storage,\n    bytes32 param,\n    uint256 paramMapping\n  ) internal view returns (bytes32) {\n    if (paramMapping > 0) {\n      return _storage.returnedValues[paramMapping - 1];\n    }\n\n    return param;\n  }\n\n  function readUint(\n    StorageSlot.TransactionStorage storage _storage,\n    bytes32 param,\n    uint256 paramMapping\n  ) internal view returns (uint256) {\n    return uint256(read(_storage, param, paramMapping));\n  }\n}\n\n/**\n * @title Used to write to the StorageSlot\n * @notice There is a structure used in the StorageSlot library that is used\n * to create a storage pointer. This library writes to a specific property of that structure\n * that is responsible for sharing the returned values from an Action.\n */\nlibrary Write {\n  function write(StorageSlot.TransactionStorage storage _storage, bytes32 value) internal {\n    _storage.returnedValues.push(value);\n  }\n}\n\nabstract contract UseStorageSlot {\n  function store() internal pure returns (StorageSlot.TransactionStorage storage) {\n    return StorageSlot.getTransactionStorage();\n  }\n}"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 0
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "libraries": {}
    }
  }}