ETH Price: $3,164.90 (+1.44%)
Gas: 2 Gwei

Contract

0x839eeb8C62162f20f3B15163D4253e266C70f84f
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60a06040190206942024-01-16 16:37:59179 days ago1705423079IN
 Create: MorphoBlueDeposit
0 ETH0.0240542241.94745245

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MorphoBlueDeposit

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 0 runs

Other Settings:
default evmVersion
File 1 of 9 : Deposit.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.15;

import { Executable } from "../common/Executable.sol";
import { UseStore, Write, Read } from "../common/UseStore.sol";
import { OperationStorage } from "../../core/OperationStorage.sol";
import { DepositData } from "../../core/types/MorphoBlue.sol";
import { MORPHO_BLUE } from "../../core/constants/MorphoBlue.sol";
import { IMorpho } from "../../interfaces/morpho-blue/IMorpho.sol";

/**
 * @title Deposit | Morpho Blue Action contract
 * @notice Deposits the specified asset as collateral on MorphoBlue's lending pool
 */
contract MorphoBlueDeposit is Executable, UseStore {
  using Write for OperationStorage;
  using Read for OperationStorage;

  constructor(address _registry) UseStore(_registry) {}

  /**
   * @dev Look at UseStore.sol to get additional info on paramsMapping
   *
   * @param data Encoded calldata that conforms to the DepositData struct
   * @param paramsMap Maps operation storage values by index (index offset by +1) to execute calldata params
   */
  function execute(bytes calldata data, uint8[] memory paramsMap) external payable override {
    DepositData memory depositData = parseInputs(data);

    uint256 mappedDepositAmount = store().readUint(
      bytes32(depositData.amount),
      paramsMap[1],
      address(this)
    );

    uint256 actualDepositAmount = depositData.sumAmounts
      ? mappedDepositAmount + depositData.amount
      : mappedDepositAmount;

    IMorpho morphoBlue = IMorpho(registry.getRegisteredService(MORPHO_BLUE));
    morphoBlue.supplyCollateral(
      depositData.marketParams,
      actualDepositAmount,
      address(this),
      bytes("")
    );

    store().write(bytes32(actualDepositAmount));
  }

  function parseInputs(bytes memory _callData) public pure returns (DepositData memory params) {
    return abi.decode(_callData, (DepositData));
  }
}

File 2 of 9 : Executable.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.15;

/**
 * @title Shared Action Executable interface
 * @notice Provides a dma-common interface for an execute method to all Action
 */
interface Executable {
  function execute(bytes calldata data, uint8[] memory paramsMap) external payable;
}

File 3 of 9 : UseStore.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.15;

import { OperationStorage } from "../../core/OperationStorage.sol";
import { ServiceRegistry } from "../../core/ServiceRegistry.sol";
import { OPERATION_STORAGE } from "../../core/constants/Common.sol";

/**
 * @title UseStore contract
 * @notice Provides access to the OperationStorage contract
 * @dev Is used by Action dma-contracts to store and retrieve values from Operation Storage.
 * @dev Previously stored values are used to override values passed to Actions during Operation execution
 */
abstract contract UseStore {
  ServiceRegistry internal immutable registry;

  constructor(address _registry) {
    registry = ServiceRegistry(_registry);
  }

  function store() internal view returns (OperationStorage) {
    return OperationStorage(registry.getRegisteredService(OPERATION_STORAGE));
  }
}

library Read {
  function read(
    OperationStorage _storage,
    bytes32 param,
    uint256 paramMapping,
    address who
  ) internal view returns (bytes32) {
    if (paramMapping > 0) {
      return _storage.at(paramMapping - 1, who);
    }

    return param;
  }

  function readUint(
    OperationStorage _storage,
    bytes32 param,
    uint256 paramMapping,
    address who
  ) internal view returns (uint256) {
    return uint256(read(_storage, param, paramMapping, who));
  }
}

library Write {
  function write(OperationStorage _storage, bytes32 value) internal {
    _storage.push(value);
  }
}

File 4 of 9 : Common.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.15;

string constant OPERATION_STORAGE = "OperationStorage_2";
string constant OPERATION_EXECUTOR = "OperationExecutor_2";
string constant OPERATIONS_REGISTRY = "OperationsRegistry_2";
string constant CHAINLOG_VIEWER = "ChainLogView";
string constant ONE_INCH_AGGREGATOR = "OneInchAggregator";
string constant DS_GUARD_FACTORY = "DSGuardFactory";
string constant WETH = "WETH";
string constant DAI = "DAI";
uint256 constant RAY = 10 ** 27;
bytes32 constant NULL = "";

/**
 * @dev We do not include patch versions in contract names to allow
 * for hotfixes of Action dma-contracts
 * and to limit updates to TheGraph
 * if the types encoded in emitted events change then use a minor version and
 * update the ServiceRegistry with a new entry
 * and update TheGraph decoding accordingly
 */
string constant POSITION_CREATED_ACTION = "PositionCreated";

string constant UNISWAP_ROUTER = "UniswapRouter";
string constant SWAP = "Swap";

address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

File 5 of 9 : MorphoBlue.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.15;

string constant MORPHO_BLUE = "MorphoBlue";

File 6 of 9 : OperationStorage.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.15;

import { ServiceRegistry } from "./ServiceRegistry.sol";

/**
 * @title Operation Storage
 * @notice Stores the return values from Actions during an Operation's execution
 * @dev valuesHolders is an array of t/x initiators (msg.sender) who have pushed values to Operation Storage
 * returnValues is a mapping between a msg.sender and an array of Action return values generated by that senders transaction
 */
contract OperationStorage {
  uint8 internal action = 0;
  bytes32[] public actions;
  bool[] public optionals;
  mapping(address => bytes32[]) public returnValues;
  address[] public valuesHolders;
  bool private locked;
  address private whoLocked;
  address public initiator;
  address immutable operationExecutorAddress;

  ServiceRegistry internal immutable registry;

  constructor(ServiceRegistry _registry, address _operationExecutorAddress) {
    registry = _registry;
    operationExecutorAddress = _operationExecutorAddress;
  }

  /**
   * @dev Locks storage to protect against re-entrancy attacks.@author
   */
  function lock() external {
    locked = true;
    whoLocked = msg.sender;
  }

  /**
   * @dev Only the original locker can unlock the contract at the end of the transaction
   */
  function unlock() external {
    require(whoLocked == msg.sender, "Only the locker can unlock");
    require(locked, "Not locked");
    locked = false;
    whoLocked = address(0);
  }

  /**
   * @dev Sets the initiator of the original call
   * Is used by Automation Bot branch in the onFlashloan callback in Operation Executor
   * Ensures that third party calls to Operation Storage do not maliciously override values in Operation Storage
   * @param _initiator Sets the initiator to Operation Executor contract when storing return values from flashloan nested Action
   */
  function setInitiator(address _initiator) external {
    require(msg.sender == operationExecutorAddress);
    initiator = _initiator;
  }

  /**
   * @param _actions Stores the Actions currently being executed for a given Operation and their optionality
   */
  function setOperationActions(bytes32[] memory _actions, bool[] memory _optionals) external {
    actions = _actions;
    optionals = _optionals;
  }

  /**
   * @param actionHash Checks the current action has against the expected action hash
   */
  function verifyAction(bytes32 actionHash, bool skipped) external {
    if (skipped) {
      require(optionals[action], "Action cannot be skipped");
    }
    require(actions[action] == actionHash, "incorrect-action");
    registry.getServiceAddress(actionHash);
    action++;
  }

  /**
   * @dev Custom operations have no Actions stored in Operation Registry
   * @return Returns true / false depending on whether the Operation has any actions to verify the Operation against
   */
  function hasActionsToVerify() external view returns (bool) {
    return actions.length > 0;
  }

  /**
   * @param value Pushes a bytes32 to end of the returnValues array
   */
  function push(bytes32 value) external {
    address who = msg.sender;
    if (who == operationExecutorAddress) {
      who = initiator;
    }

    if (returnValues[who].length == 0) {
      valuesHolders.push(who);
    }
    returnValues[who].push(value);
  }

  /**
   * @dev Values are stored against an address (who)
   * This ensures that malicious actors looking to push values to Operation Storage mid transaction cannot overwrite values
   * @param index The index of the desired value
   * @param who The msg.sender address responsible for storing values
   */
  function at(uint256 index, address who) external view returns (bytes32) {
    if (who == operationExecutorAddress) {
      who = initiator;
    }
    return returnValues[who][index];
  }

  /**
   * @param who The msg.sender address responsible for storing values
   * @return The length of return values stored against a given msg.sender address
   */
  function len(address who) external view returns (uint256) {
    if (who == operationExecutorAddress) {
      who = initiator;
    }
    return returnValues[who].length;
  }

  /**
   * @dev Clears storage in preparation for the next Operation
   */
  function clearStorage() external {
    delete action;
    delete actions;
    for (uint256 i = 0; i < valuesHolders.length; i++) {
      delete returnValues[valuesHolders[i]];
    }
    delete valuesHolders;
  }
}

File 7 of 9 : ServiceRegistry.sol
// SPDX-License-Identifier: AGPL-3.0-or-later

/// ServiceRegistry.sol

// Copyright (C) 2021-2021 Oazo Apps Limited

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
pragma solidity ^0.8.0;

contract ServiceRegistry {
  uint256 public constant MAX_DELAY = 30 days;

  mapping(bytes32 => uint256) public lastExecuted;
  mapping(bytes32 => address) private namedService;
  mapping(bytes32 => bool) private invalidHashes;
  address public owner;
  uint256 public requiredDelay;

  modifier validateInput(uint256 len) {
    require(msg.data.length == len, "registry/illegal-padding");
    _;
  }

  modifier delayedExecution() {
    bytes32 operationHash = keccak256(msg.data);
    uint256 reqDelay = requiredDelay;

    /* solhint-disable not-rely-on-time */
    if (lastExecuted[operationHash] == 0 && reqDelay > 0) {
      // not called before, scheduled for execution
      lastExecuted[operationHash] = block.timestamp;
      emit ChangeScheduled(operationHash, block.timestamp + reqDelay, msg.data);
    } else {
      require(block.timestamp - reqDelay > lastExecuted[operationHash], "registry/delay-too-small");
      emit ChangeApplied(operationHash, block.timestamp, msg.data);
      _;
      lastExecuted[operationHash] = 0;
    }
    /* solhint-enable not-rely-on-time */
  }

  modifier onlyOwner() {
    require(msg.sender == owner, "registry/only-owner");
    _;
  }

  constructor(uint256 initialDelay) {
    require(initialDelay <= MAX_DELAY, "registry/invalid-delay");
    requiredDelay = initialDelay;
    owner = msg.sender;
  }

  function transferOwnership(
    address newOwner
  ) external onlyOwner validateInput(36) delayedExecution {
    owner = newOwner;
  }

  function changeRequiredDelay(
    uint256 newDelay
  ) external onlyOwner validateInput(36) delayedExecution {
    require(newDelay <= MAX_DELAY, "registry/invalid-delay");
    requiredDelay = newDelay;
  }

  function getServiceNameHash(string memory name) external pure returns (bytes32) {
    return keccak256(abi.encodePacked(name));
  }

  function addNamedService(
    bytes32 serviceNameHash,
    address serviceAddress
  ) external onlyOwner validateInput(68) delayedExecution {
    require(invalidHashes[serviceNameHash] == false, "registry/service-name-used-before");
    require(namedService[serviceNameHash] == address(0), "registry/service-override");
    namedService[serviceNameHash] = serviceAddress;
    emit NamedServiceAdded(serviceNameHash, serviceAddress);
  }

  function removeNamedService(bytes32 serviceNameHash) external onlyOwner validateInput(36) {
    require(namedService[serviceNameHash] != address(0), "registry/service-does-not-exist");
    namedService[serviceNameHash] = address(0);
    invalidHashes[serviceNameHash] = true;
    emit NamedServiceRemoved(serviceNameHash);
  }

  function getRegisteredService(string memory serviceName) external view returns (address) {
    return namedService[keccak256(abi.encodePacked(serviceName))];
  }

  function getServiceAddress(bytes32 serviceNameHash) external view returns (address) {
    return namedService[serviceNameHash];
  }

  function clearScheduledExecution(
    bytes32 scheduledExecution
  ) external onlyOwner validateInput(36) {
    require(lastExecuted[scheduledExecution] > 0, "registry/execution-not-scheduled");
    lastExecuted[scheduledExecution] = 0;
    emit ChangeCancelled(scheduledExecution);
  }

  event ChangeScheduled(bytes32 dataHash, uint256 scheduledFor, bytes data);
  event ChangeApplied(bytes32 dataHash, uint256 appliedAt, bytes data);
  event ChangeCancelled(bytes32 dataHash);
  event NamedServiceRemoved(bytes32 nameHash);
  event NamedServiceAdded(bytes32 nameHash, address service);
}

File 8 of 9 : MorphoBlue.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.15;

import { MarketParams } from "../../interfaces/morpho-blue/IMorpho.sol";

struct DepositData {
  MarketParams marketParams;
  uint256 amount;
  bool sumAmounts;
}

struct BorrowData {
  MarketParams marketParams;
  uint256 amount;
}

struct WithdrawData {
  MarketParams marketParams;
  uint256 amount;
  address to;
}

struct PaybackData {
  MarketParams marketParams;
  uint256 amount;
  address onBehalf;
}

File 9 of 9 : IMorpho.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

type Id is bytes32;

struct MarketParams {
  address loanToken;
  address collateralToken;
  address oracle;
  address irm;
  uint256 lltv;
}

/// @dev Warning: For `feeRecipient`, `supplyShares` does not contain the accrued shares since the last interest
/// accrual.
struct Position {
  uint256 supplyShares;
  uint128 borrowShares;
  uint128 collateral;
}

/// @dev Warning: `totalSupplyAssets` does not contain the accrued interest since the last interest accrual.
/// @dev Warning: `totalBorrowAssets` does not contain the accrued interest since the last interest accrual.
/// @dev Warning: `totalSupplyShares` does not contain the additional shares accrued by `feeRecipient` since the last
/// interest accrual.
struct Market {
  uint128 totalSupplyAssets;
  uint128 totalSupplyShares;
  uint128 totalBorrowAssets;
  uint128 totalBorrowShares;
  uint128 lastUpdate;
  uint128 fee;
}

struct Authorization {
  address authorizer;
  address authorized;
  bool isAuthorized;
  uint256 nonce;
  uint256 deadline;
}

struct Signature {
  uint8 v;
  bytes32 r;
  bytes32 s;
}

/// @title IMorpho
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Interface of Morpho.
interface IMorpho {
  /// @notice The EIP-712 domain separator.
  /// @dev Warning: In case of a hardfork, every EIP-712 signed message based on this domain separator can be reused
  /// on the forked chain because the domain separator would be the same.
  function DOMAIN_SEPARATOR() external view returns (bytes32);

  /// @notice The owner of the contract.
  /// @dev It has the power to change the owner.
  /// @dev It has the power to set fees on markets and set the fee recipient.
  /// @dev It has the power to enable but not disable IRMs and LLTVs.
  function owner() external view returns (address);

  /// @notice The fee recipient of all markets.
  /// @dev The recipient receives the fees of a given market through a supply position on that market.
  function feeRecipient() external view returns (address);

  /// @notice The state of the position of `user` on the market corresponding to `id`.
  function position(
    Id id,
    address user
  ) external view returns (uint256 supplyShares, uint128 borrowShares, uint128 collateral);

  /// @notice The state of the market corresponding to `id`.
  function market(
    Id id
  )
    external
    view
    returns (
      uint128 totalSupplyAssets,
      uint128 totalSupplyShares,
      uint128 totalBorrowAssets,
      uint128 totalBorrowShares,
      uint128 lastUpdate,
      uint128 fee
    );

  /// @notice Whether the `irm` is enabled.
  function isIrmEnabled(address irm) external view returns (bool);

  /// @notice Whether the `lltv` is enabled.
  function isLltvEnabled(uint256 lltv) external view returns (bool);

  /// @notice Whether `authorized` is authorized to modify `authorizer`'s positions.
  /// @dev Anyone is authorized to modify their own positions, regardless of this variable.
  function isAuthorized(address authorizer, address authorized) external view returns (bool);

  /// @notice The `authorizer`'s current nonce. Used to prevent replay attacks with EIP-712 signatures.
  function nonce(address authorizer) external view returns (uint256);

  /// @notice The market params corresponding to `id`.
  /// @dev This mapping is not used in Morpho. It is there to enable reducing the cost associated to calldata on layer
  /// 2s by creating a wrapper contract with functions that take `id` as input instead of `marketParams`.
  function idToMarketParams(
    Id id
  )
    external
    view
    returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv);

  /// @notice Sets `newOwner` as owner of the contract.
  /// @dev Warning: No two-step transfer ownership.
  /// @dev Warning: The owner can be set to the zero address.
  function setOwner(address newOwner) external;

  /// @notice Enables `irm` as a possible IRM for market creation.
  /// @dev Warning: It is not possible to disable an IRM.
  function enableIrm(address irm) external;

  /// @notice Enables `lltv` as a possible LLTV for market creation.
  /// @dev Warning: It is not possible to disable a LLTV.
  function enableLltv(uint256 lltv) external;

  /// @notice Sets the `newFee` for the given market `marketParams`.
  /// @dev Warning: The recipient can be the zero address.
  function setFee(MarketParams memory marketParams, uint256 newFee) external;

  /// @notice Sets `newFeeRecipient` as recipient of the fee.
  /// @dev Warning: The fee recipient can be set to the zero address.
  /// @dev Warning: The fee to be accrued on each market won't belong to the old fee recipient after calling this
  /// function.
  function setFeeRecipient(address newFeeRecipient) external;

  /// @notice Creates the market `marketParams`.
  /// @dev Here is the list of assumptions on the market's dependencies (tokens, IRM and oracle) that guarantees
  /// Morpho behaves as expected:
  /// - The token should be ERC-20 compliant, except that it can omit return values on `transfer` and `transferFrom`.
  /// - The token balance of Morpho should only decrease on `transfer` and `transferFrom`. In particular, tokens with
  /// burn functions are not supported.
  /// - The token should not re-enter Morpho on `transfer` nor `transferFrom`.
  /// - The token balance of the sender (resp. receiver) should decrease (resp. increase) by exactly the given amount
  /// on `transfer` and `transferFrom`. In particular, tokens with fees on transfer are not supported.
  /// - The IRM should not re-enter Morpho.
  /// @dev Here is a list of properties on the market's dependencies that could break Morpho's liveness properties:
  /// - The token can revert on `transfer` and `transferFrom` for a reason other than an approval or balance issue.
  /// - A very high amount of assets (~1e35) supplied or borrowed can make the computation of `toSharesUp` and
  /// `toSharesDown` overflow.
  /// - The IRM can revert on `borrowRate`.
  /// - A very high borrow rate returned by the IRM can make the computation of `interest` in `_accrueInterest`
  /// overflow.
  /// - The oracle can revert on `price`. Note that this can be used to prevent `borrow`, `withdrawCollateral` and
  /// `liquidate` from being used under certain market conditions.
  /// - A very high price returned by the oracle can make the computation of `maxBorrow` in `_isHealthy` overflow, or
  /// the computation of `assetsRepaid` in `liquidate` overflow.
  function createMarket(MarketParams memory marketParams) external;

  /// @notice Supplies `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's
  /// `onMorphoSupply` function with the given `data`.
  /// @dev Either `assets` or `shares` should be zero. Most usecases should rely on `assets` as an input so the caller
  /// is guaranteed to have `assets` tokens pulled from their balance, but the possibility to mint a specific amount
  /// of shares is given for full compatibility and precision.
  /// @dev Supplying a large amount can revert for overflow.
  /// @param marketParams The market to supply assets to.
  /// @param assets The amount of assets to supply.
  /// @param shares The amount of shares to mint.
  /// @param onBehalf The address that will own the increased supply position.
  /// @param data Arbitrary data to pass to the `onMorphoSupply` callback. Pass empty data if not needed.
  /// @return assetsSupplied The amount of assets supplied.
  /// @return sharesSupplied The amount of shares minted.
  function supply(
    MarketParams memory marketParams,
    uint256 assets,
    uint256 shares,
    address onBehalf,
    bytes memory data
  ) external returns (uint256 assetsSupplied, uint256 sharesSupplied);

  /// @notice Withdraws `assets` or `shares` on behalf of `onBehalf` to `receiver`.
  /// @dev Either `assets` or `shares` should be zero. To withdraw max, pass the `shares`'s balance of `onBehalf`.
  /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.
  /// @dev Withdrawing an amount corresponding to more shares than supplied will revert for underflow.
  /// @param marketParams The market to withdraw assets from.
  /// @param assets The amount of assets to withdraw.
  /// @param shares The amount of shares to burn.
  /// @param onBehalf The address of the owner of the supply position.
  /// @param receiver The address that will receive the withdrawn assets.
  /// @return assetsWithdrawn The amount of assets withdrawn.
  /// @return sharesWithdrawn The amount of shares burned.
  function withdraw(
    MarketParams memory marketParams,
    uint256 assets,
    uint256 shares,
    address onBehalf,
    address receiver
  ) external returns (uint256 assetsWithdrawn, uint256 sharesWithdrawn);

  /// @notice Borrows `assets` or `shares` on behalf of `onBehalf` to `receiver`.
  /// @dev Either `assets` or `shares` should be zero. Most usecases should rely on `assets` as an input so the caller
  /// is guaranteed to borrow `assets` of tokens, but the possibility to mint a specific amount of shares is given for
  /// full compatibility and precision.
  /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.
  /// @dev Borrowing a large amount can revert for overflow.
  /// @param marketParams The market to borrow assets from.
  /// @param assets The amount of assets to borrow.
  /// @param shares The amount of shares to mint.
  /// @param onBehalf The address that will own the increased borrow position.
  /// @param receiver The address that will receive the borrowed assets.
  /// @return assetsBorrowed The amount of assets borrowed.
  /// @return sharesBorrowed The amount of shares minted.
  function borrow(
    MarketParams memory marketParams,
    uint256 assets,
    uint256 shares,
    address onBehalf,
    address receiver
  ) external returns (uint256 assetsBorrowed, uint256 sharesBorrowed);

  /// @notice Repays `assets` or `shares` on behalf of `onBehalf`, optionally calling back the caller's
  /// `onMorphoReplay` function with the given `data`.
  /// @dev Either `assets` or `shares` should be zero. To repay max, pass the `shares`'s balance of `onBehalf`.
  /// @dev Repaying an amount corresponding to more shares than borrowed will revert for underflow.
  /// @param marketParams The market to repay assets to.
  /// @param assets The amount of assets to repay.
  /// @param shares The amount of shares to burn.
  /// @param onBehalf The address of the owner of the debt position.
  /// @param data Arbitrary data to pass to the `onMorphoRepay` callback. Pass empty data if not needed.
  /// @return assetsRepaid The amount of assets repaid.
  /// @return sharesRepaid The amount of shares burned.
  function repay(
    MarketParams memory marketParams,
    uint256 assets,
    uint256 shares,
    address onBehalf,
    bytes memory data
  ) external returns (uint256 assetsRepaid, uint256 sharesRepaid);

  /// @notice Supplies `assets` of collateral on behalf of `onBehalf`, optionally calling back the caller's
  /// `onMorphoSupplyCollateral` function with the given `data`.
  /// @dev Interest are not accrued since it's not required and it saves gas.
  /// @dev Supplying a large amount can revert for overflow.
  /// @param marketParams The market to supply collateral to.
  /// @param assets The amount of collateral to supply.
  /// @param onBehalf The address that will own the increased collateral position.
  /// @param data Arbitrary data to pass to the `onMorphoSupplyCollateral` callback. Pass empty data if not needed.
  function supplyCollateral(
    MarketParams memory marketParams,
    uint256 assets,
    address onBehalf,
    bytes memory data
  ) external;

  /// @notice Withdraws `assets` of collateral on behalf of `onBehalf` to `receiver`.
  /// @dev `msg.sender` must be authorized to manage `onBehalf`'s positions.
  /// @dev Withdrawing an amount corresponding to more collateral than supplied will revert for underflow.
  /// @param marketParams The market to withdraw collateral from.
  /// @param assets The amount of collateral to withdraw.
  /// @param onBehalf The address of the owner of the collateral position.
  /// @param receiver The address that will receive the collateral assets.
  function withdrawCollateral(
    MarketParams memory marketParams,
    uint256 assets,
    address onBehalf,
    address receiver
  ) external;

  /// @notice Liquidates the given `repaidShares` of debt asset or seize the given `seizedAssets` of collateral on the
  /// given market `marketParams` of the given `borrower`'s position, optionally calling back the caller's
  /// `onMorphoLiquidate` function with the given `data`.
  /// @dev Either `seizedAssets` or `repaidShares` should be zero.
  /// @dev Seizing more than the collateral balance will underflow and revert without any error message.
  /// @dev Repaying more than the borrow balance will underflow and revert without any error message.
  /// @param marketParams The market of the position.
  /// @param borrower The owner of the position.
  /// @param seizedAssets The amount of collateral to seize.
  /// @param repaidShares The amount of shares to repay.
  /// @param data Arbitrary data to pass to the `onMorphoLiquidate` callback. Pass empty data if not needed.
  /// @return The amount of assets seized.
  /// @return The amount of assets repaid.
  function liquidate(
    MarketParams memory marketParams,
    address borrower,
    uint256 seizedAssets,
    uint256 repaidShares,
    bytes memory data
  ) external returns (uint256, uint256);

  /// @notice Executes a flash loan.
  /// @dev Flash loans have access to the whole balance of the contract (the liquidity and deposited collateral of all
  /// markets combined, plus donations).
  /// @param token The token to flash loan.
  /// @param assets The amount of assets to flash loan.
  /// @param data Arbitrary data to pass to the `onMorphoFlashLoan` callback.
  function flashLoan(address token, uint256 assets, bytes calldata data) external;

  /// @notice Sets the authorization for `authorized` to manage `msg.sender`'s positions.
  /// @param authorized The authorized address.
  /// @param newIsAuthorized The new authorization status.
  function setAuthorization(address authorized, bool newIsAuthorized) external;

  /// @notice Sets the authorization for `authorization.authorized` to manage `authorization.authorizer`'s positions.
  /// @dev Warning: Reverts if the signature has already been submitted.
  /// @dev The signature is malleable, but it has no impact on the security here.
  /// @dev The nonce is passed as argument to be able to revert with a different error message.
  /// @param authorization The `Authorization` struct.
  /// @param signature The signature.
  function setAuthorizationWithSig(
    Authorization calldata authorization,
    Signature calldata signature
  ) external;

  /// @notice Returns the data stored on the different `slots`.
  function extSloads(bytes32[] memory slots) external view returns (bytes32[] memory);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 0
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_registry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint8[]","name":"paramsMap","type":"uint8[]"}],"name":"execute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_callData","type":"bytes"}],"name":"parseInputs","outputs":[{"components":[{"components":[{"internalType":"address","name":"loanToken","type":"address"},{"internalType":"address","name":"collateralToken","type":"address"},{"internalType":"address","name":"oracle","type":"address"},{"internalType":"address","name":"irm","type":"address"},{"internalType":"uint256","name":"lltv","type":"uint256"}],"internalType":"struct MarketParams","name":"marketParams","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"sumAmounts","type":"bool"}],"internalType":"struct DepositData","name":"params","type":"tuple"}],"stateMutability":"pure","type":"function"}]

60a060405234801561001057600080fd5b506040516109f43803806109f483398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b6080516109626100926000396000818161015f015261030801526109626000f3fe6080604052600436106100295760003560e01c806385e92d981461002e5780639093410d14610043575b600080fd5b61004161003c366004610507565b610079565b005b34801561004f57600080fd5b5061006361005e366004610618565b61026f565b60405161007091906106eb565b60405180910390f35b60006100ba84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061026f92505050565b90506000610101826020015160001b846001815181106100dc576100dc610719565b602002602001015160ff16306100f06102c7565b6001600160a01b0316929190610381565b9050600082604001516101145781610123565b60208301516101239083610745565b604080518082018252600a8152694d6f7270686f426c756560b01b60208201529051630851f3bd60e01b81529192506000916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691630851f3bd91610193919060040161079e565b602060405180830381865afa1580156101b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d491906107d4565b84516040805160208101825260008152905163238d657960e01b81529293506001600160a01b0384169263238d657992610216929091879130916004016107ef565b600060405180830381600087803b15801561023057600080fd5b505af1158015610244573d6000803e3d6000fd5b505050506102668260001b6102576102c7565b6001600160a01b03169061039a565b50505050505050565b60408051610100810182526000606082018181526080830182905260a0830182905260c0830182905260e083018290528252602080830182905292820152825190916102c19184018101908401610842565b92915050565b604080518082018252601281527127b832b930ba34b7b729ba37b930b3b2af9960711b60208201529051630851f3bd60e01b81526000916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691630851f3bd9161033b9160040161079e565b602060405180830381865afa158015610358573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037c91906107d4565b905090565b600061038f858585856103f8565b90505b949350505050565b60405163b298e36b60e01b8152600481018290526001600160a01b0383169063b298e36b90602401600060405180830381600087803b1580156103dc57600080fd5b505af11580156103f0573d6000803e3d6000fd5b505050505050565b60008215610490576001600160a01b03851663a729351b61041a600186610900565b6040516001600160e01b031960e084901b16815260048101919091526001600160a01b0385166024820152604401602060405180830381865afa158015610465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104899190610913565b9050610392565b50919392505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156104d1576104d1610499565b60405290565b604051601f8201601f191681016001600160401b03811182821017156104ff576104ff610499565b604052919050565b60008060006040848603121561051c57600080fd5b83356001600160401b038082111561053357600080fd5b818601915086601f83011261054757600080fd5b81358181111561055657600080fd5b6020888183860101111561056957600080fd5b80840196508195508088013593508284111561058457600080fd5b838801935088601f85011261059857600080fd5b83359150828211156105ac576105ac610499565b8160051b92506105bd8184016104d7565b828152928401810192818101908a8511156105d757600080fd5b948201945b84861015610608578535935060ff841684146105f85760008081fd5b83825294820194908201906105dc565b8096505050505050509250925092565b6000602080838503121561062b57600080fd5b82356001600160401b038082111561064257600080fd5b818501915085601f83011261065657600080fd5b81358181111561066857610668610499565b61067a601f8201601f191685016104d7565b9150808252868482850101111561069057600080fd5b8084840185840137600090820190930192909252509392505050565b80516001600160a01b03908116835260208083015182169084015260408083015182169084015260608083015190911690830152608090810151910152565b600060e0820190506106fe8284516106ac565b602083015160a0830152604090920151151560c09091015290565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156102c1576102c161072f565b6000815180845260005b8181101561077e57602081850181015186830182015201610762565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006107b16020830184610758565b9392505050565b80516001600160a01b03811681146107cf57600080fd5b919050565b6000602082840312156107e657600080fd5b6107b1826107b8565b60006101006107fe83886106ac565b60a083018690526001600160a01b03851660c084015260e0830181905261082781840185610758565b979650505050505050565b805180151581146107cf57600080fd5b600081830360e081121561085557600080fd5b604051606081016001600160401b038111828210171561087757610877610499565b60405260a082121561088857600080fd5b6108906104af565b915061089b846107b8565b82526108a9602085016107b8565b60208301526108ba604085016107b8565b60408301526108cb606085016107b8565b60608301526080840151608083015281815260a084015160208201526108f360c08501610832565b6040820152949350505050565b818103818111156102c1576102c161072f565b60006020828403121561092557600080fd5b505191905056fea2646970667358221220ed110bfc1b8837ca192607d8fc9d50bd366e469b46638633df59c200db3b7aab64736f6c634300081300330000000000000000000000005e81a7515f956ab642eb698821a449fe8fe7498e

Deployed Bytecode

0x6080604052600436106100295760003560e01c806385e92d981461002e5780639093410d14610043575b600080fd5b61004161003c366004610507565b610079565b005b34801561004f57600080fd5b5061006361005e366004610618565b61026f565b60405161007091906106eb565b60405180910390f35b60006100ba84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061026f92505050565b90506000610101826020015160001b846001815181106100dc576100dc610719565b602002602001015160ff16306100f06102c7565b6001600160a01b0316929190610381565b9050600082604001516101145781610123565b60208301516101239083610745565b604080518082018252600a8152694d6f7270686f426c756560b01b60208201529051630851f3bd60e01b81529192506000916001600160a01b037f0000000000000000000000005e81a7515f956ab642eb698821a449fe8fe7498e1691630851f3bd91610193919060040161079e565b602060405180830381865afa1580156101b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d491906107d4565b84516040805160208101825260008152905163238d657960e01b81529293506001600160a01b0384169263238d657992610216929091879130916004016107ef565b600060405180830381600087803b15801561023057600080fd5b505af1158015610244573d6000803e3d6000fd5b505050506102668260001b6102576102c7565b6001600160a01b03169061039a565b50505050505050565b60408051610100810182526000606082018181526080830182905260a0830182905260c0830182905260e083018290528252602080830182905292820152825190916102c19184018101908401610842565b92915050565b604080518082018252601281527127b832b930ba34b7b729ba37b930b3b2af9960711b60208201529051630851f3bd60e01b81526000916001600160a01b037f0000000000000000000000005e81a7515f956ab642eb698821a449fe8fe7498e1691630851f3bd9161033b9160040161079e565b602060405180830381865afa158015610358573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037c91906107d4565b905090565b600061038f858585856103f8565b90505b949350505050565b60405163b298e36b60e01b8152600481018290526001600160a01b0383169063b298e36b90602401600060405180830381600087803b1580156103dc57600080fd5b505af11580156103f0573d6000803e3d6000fd5b505050505050565b60008215610490576001600160a01b03851663a729351b61041a600186610900565b6040516001600160e01b031960e084901b16815260048101919091526001600160a01b0385166024820152604401602060405180830381865afa158015610465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104899190610913565b9050610392565b50919392505050565b634e487b7160e01b600052604160045260246000fd5b60405160a081016001600160401b03811182821017156104d1576104d1610499565b60405290565b604051601f8201601f191681016001600160401b03811182821017156104ff576104ff610499565b604052919050565b60008060006040848603121561051c57600080fd5b83356001600160401b038082111561053357600080fd5b818601915086601f83011261054757600080fd5b81358181111561055657600080fd5b6020888183860101111561056957600080fd5b80840196508195508088013593508284111561058457600080fd5b838801935088601f85011261059857600080fd5b83359150828211156105ac576105ac610499565b8160051b92506105bd8184016104d7565b828152928401810192818101908a8511156105d757600080fd5b948201945b84861015610608578535935060ff841684146105f85760008081fd5b83825294820194908201906105dc565b8096505050505050509250925092565b6000602080838503121561062b57600080fd5b82356001600160401b038082111561064257600080fd5b818501915085601f83011261065657600080fd5b81358181111561066857610668610499565b61067a601f8201601f191685016104d7565b9150808252868482850101111561069057600080fd5b8084840185840137600090820190930192909252509392505050565b80516001600160a01b03908116835260208083015182169084015260408083015182169084015260608083015190911690830152608090810151910152565b600060e0820190506106fe8284516106ac565b602083015160a0830152604090920151151560c09091015290565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808201808211156102c1576102c161072f565b6000815180845260005b8181101561077e57602081850181015186830182015201610762565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006107b16020830184610758565b9392505050565b80516001600160a01b03811681146107cf57600080fd5b919050565b6000602082840312156107e657600080fd5b6107b1826107b8565b60006101006107fe83886106ac565b60a083018690526001600160a01b03851660c084015260e0830181905261082781840185610758565b979650505050505050565b805180151581146107cf57600080fd5b600081830360e081121561085557600080fd5b604051606081016001600160401b038111828210171561087757610877610499565b60405260a082121561088857600080fd5b6108906104af565b915061089b846107b8565b82526108a9602085016107b8565b60208301526108ba604085016107b8565b60408301526108cb606085016107b8565b60608301526080840151608083015281815260a084015160208201526108f360c08501610832565b6040820152949350505050565b818103818111156102c1576102c161072f565b60006020828403121561092557600080fd5b505191905056fea2646970667358221220ed110bfc1b8837ca192607d8fc9d50bd366e469b46638633df59c200db3b7aab64736f6c63430008130033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000005e81a7515f956ab642eb698821a449fe8fe7498e

-----Decoded View---------------
Arg [0] : _registry (address): 0x5E81A7515F956ab642Eb698821a449FE8fE7498e

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000005e81a7515f956ab642eb698821a449fe8fe7498e


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.