ETH Price: $3,159.94 (+2.91%)
 

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Sponsored

Transaction Hash
Method
Block
From
To
Value
Create Morpho Ch...170057312024-07-12 16:13:2920 hrs ago1720800809IN
0x2DC205F2...648Aebd3d
0 ETH0.000007360.0117
Create Morpho Ch...167541842024-07-06 20:28:356 days ago1720297715IN
0x2DC205F2...648Aebd3d
0 ETH0.000001580.00253764
Create Morpho Ch...167499092024-07-06 18:06:056 days ago1720289165IN
0x2DC205F2...648Aebd3d
0 ETH0.000002160.00349246
Create Morpho Ch...166478262024-07-04 9:23:199 days ago1720084999IN
0x2DC205F2...648Aebd3d
0 ETH0.000012190.0202
Create Morpho Ch...166477732024-07-04 9:21:339 days ago1720084893IN
0x2DC205F2...648Aebd3d
0 ETH0.000012310.0204
Create Morpho Ch...165406512024-07-01 21:50:4911 days ago1719870649IN
0x2DC205F2...648Aebd3d
0 ETH0.0000060.0098
Create Morpho Ch...163236762024-06-26 21:18:1916 days ago1719436699IN
0x2DC205F2...648Aebd3d
0 ETH0.000004480.00719548
Create Morpho Ch...160874702024-06-21 10:04:4722 days ago1718964287IN
0x2DC205F2...648Aebd3d
0 ETH0.00001020.01650372
Create Morpho Ch...160523082024-06-20 14:32:4322 days ago1718893963IN
0x2DC205F2...648Aebd3d
0 ETH0.000022480.0362
Create Morpho Ch...160491142024-06-20 12:46:1522 days ago1718887575IN
0x2DC205F2...648Aebd3d
0 ETH0.000012980.0212
Create Morpho Ch...160490732024-06-20 12:44:5322 days ago1718887493IN
0x2DC205F2...648Aebd3d
0 ETH0.000013290.0211
Create Morpho Ch...160488702024-06-20 12:38:0722 days ago1718887087IN
0x2DC205F2...648Aebd3d
0 ETH0.000013220.021
Create Morpho Ch...160488412024-06-20 12:37:0922 days ago1718887029IN
0x2DC205F2...648Aebd3d
0 ETH0.00001280.0209
Create Morpho Ch...160488142024-06-20 12:36:1522 days ago1718886975IN
0x2DC205F2...648Aebd3d
0 ETH0.000012420.02
Create Morpho Ch...160456582024-06-20 10:51:0323 days ago1718880663IN
0x2DC205F2...648Aebd3d
0 ETH0.000005380.0088
Create Morpho Ch...160398122024-06-20 7:36:1123 days ago1718868971IN
0x2DC205F2...648Aebd3d
0 ETH0.000003710.00597476
Create Morpho Ch...160082502024-06-19 14:04:0723 days ago1718805847IN
0x2DC205F2...648Aebd3d
0 ETH0.000013980.02252262
Create Morpho Ch...159499642024-06-18 5:41:1525 days ago1718689275IN
0x2DC205F2...648Aebd3d
0 ETH0.000001860.003
Create Morpho Ch...159217052024-06-17 13:59:1725 days ago1718632757IN
0x2DC205F2...648Aebd3d
0 ETH0.000010980.01768871
Create Morpho Ch...156535372024-06-11 9:00:2132 days ago1718096421IN
0x2DC205F2...648Aebd3d
0 ETH0.000002970.00486078
Create Morpho Ch...156535052024-06-11 8:59:1732 days ago1718096357IN
0x2DC205F2...648Aebd3d
0 ETH0.000002940.00481127
Create Morpho Ch...156521292024-06-11 8:13:2532 days ago1718093605IN
0x2DC205F2...648Aebd3d
0 ETH0.000003290.00523035
Create Morpho Ch...156225182024-06-10 15:46:2332 days ago1718034383IN
0x2DC205F2...648Aebd3d
0 ETH0.000009350.0061292
Create Morpho Ch...145005582024-05-15 16:27:4358 days ago1715790463IN
0x2DC205F2...648Aebd3d
0 ETH0.000057560.0914

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To Value
170057312024-07-12 16:13:2920 hrs ago1720800809
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
167541842024-07-06 20:28:356 days ago1720297715
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
167499092024-07-06 18:06:056 days ago1720289165
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
166478262024-07-04 9:23:199 days ago1720084999
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
166477732024-07-04 9:21:339 days ago1720084893
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
165406512024-07-01 21:50:4911 days ago1719870649
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
164872632024-06-30 16:11:1312 days ago1719763873
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
164872632024-06-30 16:11:1312 days ago1719763873
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
164872632024-06-30 16:11:1312 days ago1719763873
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
163236762024-06-26 21:18:1916 days ago1719436699
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160874702024-06-21 10:04:4722 days ago1718964287
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160851522024-06-21 8:47:3122 days ago1718959651
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160851522024-06-21 8:47:3122 days ago1718959651
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160851522024-06-21 8:47:3122 days ago1718959651
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160851522024-06-21 8:47:3122 days ago1718959651
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160523082024-06-20 14:32:4322 days ago1718893963
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160491142024-06-20 12:46:1522 days ago1718887575
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160490732024-06-20 12:44:5322 days ago1718887493
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160488702024-06-20 12:38:0722 days ago1718887087
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160488412024-06-20 12:37:0922 days ago1718887029
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160488142024-06-20 12:36:1522 days ago1718886975
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160456582024-06-20 10:51:0323 days ago1718880663
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160398122024-06-20 7:36:1123 days ago1718868971
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
160082502024-06-19 14:04:0723 days ago1718805847
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
159499642024-06-18 5:41:1525 days ago1718689275
0x2DC205F2...648Aebd3d
 Contract Creation0 ETH
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MorphoChainlinkOracleV2Factory

Compiler Version
v0.8.21+commit.d9974bed

Optimization Enabled:
Yes with 999999 runs

Other Settings:
paris EvmVersion, GNU GPLv2 license
File 1 of 11 : MorphoChainlinkOracleV2Factory.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity 0.8.21;

import {IMorphoChainlinkOracleV2} from "./interfaces/IMorphoChainlinkOracleV2.sol";
import {IMorphoChainlinkOracleV2Factory} from "./interfaces/IMorphoChainlinkOracleV2Factory.sol";
import {AggregatorV3Interface} from "./libraries/ChainlinkDataFeedLib.sol";
import {IERC4626} from "./libraries/VaultLib.sol";

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

/// @title MorphoChainlinkOracleV2Factory
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice This contract allows to create MorphoChainlinkOracleV2 oracles, and to index them easily.
contract MorphoChainlinkOracleV2Factory is IMorphoChainlinkOracleV2Factory {
    /* STORAGE */

    /// @inheritdoc IMorphoChainlinkOracleV2Factory
    mapping(address => bool) public isMorphoChainlinkOracleV2;

    /* EXTERNAL */

    /// @inheritdoc IMorphoChainlinkOracleV2Factory
    function createMorphoChainlinkOracleV2(
        IERC4626 baseVault,
        uint256 baseVaultConversionSample,
        AggregatorV3Interface baseFeed1,
        AggregatorV3Interface baseFeed2,
        uint256 baseTokenDecimals,
        IERC4626 quoteVault,
        uint256 quoteVaultConversionSample,
        AggregatorV3Interface quoteFeed1,
        AggregatorV3Interface quoteFeed2,
        uint256 quoteTokenDecimals,
        bytes32 salt
    ) external returns (MorphoChainlinkOracleV2 oracle) {
        oracle = new MorphoChainlinkOracleV2{salt: salt}(
            baseVault,
            baseVaultConversionSample,
            baseFeed1,
            baseFeed2,
            baseTokenDecimals,
            quoteVault,
            quoteVaultConversionSample,
            quoteFeed1,
            quoteFeed2,
            quoteTokenDecimals
        );

        isMorphoChainlinkOracleV2[address(oracle)] = true;

        emit CreateMorphoChainlinkOracleV2(msg.sender, address(oracle));
    }
}

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

import {IERC4626} from "./IERC4626.sol";
import {IOracle} from "../../../lib/morpho-blue/src/interfaces/IOracle.sol";
import {AggregatorV3Interface} from "./AggregatorV3Interface.sol";

/// @title IMorphoChainlinkOracleV2
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Interface of MorphoChainlinkOracleV2.
interface IMorphoChainlinkOracleV2 is IOracle {
    /// @notice Returns the address of the base ERC4626 vault.
    function BASE_VAULT() external view returns (IERC4626);

    /// @notice Returns the base vault conversion sample.
    function BASE_VAULT_CONVERSION_SAMPLE() external view returns (uint256);

    /// @notice Returns the address of the quote ERC4626 vault.
    function QUOTE_VAULT() external view returns (IERC4626);

    /// @notice Returns the quote vault conversion sample.
    function QUOTE_VAULT_CONVERSION_SAMPLE() external view returns (uint256);

    /// @notice Returns the address of the first base feed.
    function BASE_FEED_1() external view returns (AggregatorV3Interface);

    /// @notice Returns the address of the second base feed.
    function BASE_FEED_2() external view returns (AggregatorV3Interface);

    /// @notice Returns the address of the first quote feed.
    function QUOTE_FEED_1() external view returns (AggregatorV3Interface);

    /// @notice Returns the address of the second quote feed.
    function QUOTE_FEED_2() external view returns (AggregatorV3Interface);

    /// @notice Returns the price scale factor, calculated at contract creation.
    function SCALE_FACTOR() external view returns (uint256);
}

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

import {MorphoChainlinkOracleV2} from "../MorphoChainlinkOracleV2.sol";
import {IERC4626} from "../libraries/VaultLib.sol";
import {AggregatorV3Interface} from "../libraries/ChainlinkDataFeedLib.sol";

/// @title IMorphoChainlinkOracleV2Factory
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Interface for MorphoChainlinkOracleV2Factory
interface IMorphoChainlinkOracleV2Factory {
    /// @notice Emitted when a new Chainlink oracle is created.
    /// @param oracle The address of the Chainlink oracle.
    /// @param caller The caller of the function.
    event CreateMorphoChainlinkOracleV2(address caller, address oracle);

    /// @notice Whether a Chainlink oracle vault was created with the factory.
    function isMorphoChainlinkOracleV2(address target) external view returns (bool);

    /// @dev Here is the list of assumptions that guarantees the oracle behaves as expected:
    /// - The vaults, if set, are ERC4626-compliant.
    /// - The feeds, if set, are Chainlink-interface-compliant.
    /// - Decimals passed as argument are correct.
    /// - The base vaults's sample shares quoted as assets and the base feed prices don't overflow when multiplied.
    /// - The quote vault's sample shares quoted as assets and the quote feed prices don't overflow when multiplied.
    /// @param baseVault Base vault. Pass address zero to omit this parameter.
    /// @param baseVaultConversionSample The sample amount of base vault shares used to convert to underlying.
    /// Pass 1 if the base asset is not a vault. Should be chosen such that converting `baseVaultConversionSample` to
    /// assets has enough precision.
    /// @param baseFeed1 First base feed. Pass address zero if the price = 1.
    /// @param baseFeed2 Second base feed. Pass address zero if the price = 1.
    /// @param baseTokenDecimals Base token decimals.
    /// @param quoteVault Quote vault. Pass address zero to omit this parameter.
    /// @param quoteVaultConversionSample The sample amount of quote vault shares used to convert to underlying.
    /// Pass 1 if the quote asset is not a vault. Should be chosen such that converting `quoteVaultConversionSample` to
    /// assets has enough precision.
    /// @param quoteFeed1 First quote feed. Pass address zero if the price = 1.
    /// @param quoteFeed2 Second quote feed. Pass address zero if the price = 1.
    /// @param quoteTokenDecimals Quote token decimals.
    /// @param salt The salt to use for the CREATE2.
    /// @dev The base asset should be the collateral token and the quote asset the loan token.
    function createMorphoChainlinkOracleV2(
        IERC4626 baseVault,
        uint256 baseVaultConversionSample,
        AggregatorV3Interface baseFeed1,
        AggregatorV3Interface baseFeed2,
        uint256 baseTokenDecimals,
        IERC4626 quoteVault,
        uint256 quoteVaultConversionSample,
        AggregatorV3Interface quoteFeed1,
        AggregatorV3Interface quoteFeed2,
        uint256 quoteTokenDecimals,
        bytes32 salt
    ) external returns (MorphoChainlinkOracleV2 oracle);
}

File 4 of 11 : ChainlinkDataFeedLib.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {AggregatorV3Interface} from "../interfaces/AggregatorV3Interface.sol";

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

/// @title ChainlinkDataFeedLib
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Library exposing functions to interact with a Chainlink-compliant feed.
library ChainlinkDataFeedLib {
    /// @dev Performs safety checks and returns the latest price of a `feed`.
    /// @dev When `feed` is the address zero, returns 1.
    /// @dev Notes on safety checks:
    /// - L2s are not supported.
    /// - Staleness is not checked because it's assumed that the Chainlink feed keeps its promises on this.
    /// - The price is not checked to be in the min/max bounds because it's assumed that the Chainlink feed keeps its
    /// promises on this.
    function getPrice(AggregatorV3Interface feed) internal view returns (uint256) {
        if (address(feed) == address(0)) return 1;

        (, int256 answer,,,) = feed.latestRoundData();
        require(answer >= 0, ErrorsLib.NEGATIVE_ANSWER);

        return uint256(answer);
    }

    /// @dev Returns the number of decimals of a `feed`.
    /// @dev When `feed` is the address zero, returns 0.
    function getDecimals(AggregatorV3Interface feed) internal view returns (uint256) {
        if (address(feed) == address(0)) return 0;

        return feed.decimals();
    }
}

File 5 of 11 : VaultLib.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {IERC4626} from "../interfaces/IERC4626.sol";

/// @title VaultLib
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Library exposing functions to price shares of an ERC4626 vault.
library VaultLib {
    /// @dev Converts `shares` into the corresponding assets on the `vault`.
    /// @dev When `vault` is the address zero, returns 1.
    function getAssets(IERC4626 vault, uint256 shares) internal view returns (uint256) {
        if (address(vault) == address(0)) return 1;

        return vault.convertToAssets(shares);
    }
}

File 6 of 11 : MorphoChainlinkOracleV2.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity 0.8.21;

import {IOracle} from "../../lib/morpho-blue/src/interfaces/IOracle.sol";
import {IMorphoChainlinkOracleV2} from "./interfaces/IMorphoChainlinkOracleV2.sol";

import {ErrorsLib} from "./libraries/ErrorsLib.sol";
import {IERC4626, VaultLib} from "./libraries/VaultLib.sol";
import {Math} from "../../lib/openzeppelin-contracts/contracts/utils/math/Math.sol";
import {AggregatorV3Interface, ChainlinkDataFeedLib} from "./libraries/ChainlinkDataFeedLib.sol";

/// @title MorphoChainlinkOracleV2
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Morpho Blue oracle using Chainlink-compliant feeds.
contract MorphoChainlinkOracleV2 is IMorphoChainlinkOracleV2 {
    using Math for uint256;
    using VaultLib for IERC4626;
    using ChainlinkDataFeedLib for AggregatorV3Interface;

    /* IMMUTABLES */

    /// @inheritdoc IMorphoChainlinkOracleV2
    IERC4626 public immutable BASE_VAULT;

    /// @inheritdoc IMorphoChainlinkOracleV2
    uint256 public immutable BASE_VAULT_CONVERSION_SAMPLE;

    /// @inheritdoc IMorphoChainlinkOracleV2
    IERC4626 public immutable QUOTE_VAULT;

    /// @inheritdoc IMorphoChainlinkOracleV2
    uint256 public immutable QUOTE_VAULT_CONVERSION_SAMPLE;

    /// @inheritdoc IMorphoChainlinkOracleV2
    AggregatorV3Interface public immutable BASE_FEED_1;

    /// @inheritdoc IMorphoChainlinkOracleV2
    AggregatorV3Interface public immutable BASE_FEED_2;

    /// @inheritdoc IMorphoChainlinkOracleV2
    AggregatorV3Interface public immutable QUOTE_FEED_1;

    /// @inheritdoc IMorphoChainlinkOracleV2
    AggregatorV3Interface public immutable QUOTE_FEED_2;

    /// @inheritdoc IMorphoChainlinkOracleV2
    uint256 public immutable SCALE_FACTOR;

    /* CONSTRUCTOR */

    /// @dev Here is the list of assumptions that guarantees the oracle behaves as expected:
    /// - The vaults, if set, are ERC4626-compliant.
    /// - The feeds, if set, are Chainlink-interface-compliant.
    /// - Decimals passed as argument are correct.
    /// - The base vaults's sample shares quoted as assets and the base feed prices don't overflow when multiplied.
    /// - The quote vault's sample shares quoted as assets and the quote feed prices don't overflow when multiplied.
    /// @param baseVault Base vault. Pass address zero to omit this parameter.
    /// @param baseVaultConversionSample The sample amount of base vault shares used to convert to underlying.
    /// Pass 1 if the base asset is not a vault. Should be chosen such that converting `baseVaultConversionSample` to
    /// assets has enough precision.
    /// @param baseFeed1 First base feed. Pass address zero if the price = 1.
    /// @param baseFeed2 Second base feed. Pass address zero if the price = 1.
    /// @param baseTokenDecimals Base token decimals.
    /// @param quoteVault Quote vault. Pass address zero to omit this parameter.
    /// @param quoteVaultConversionSample The sample amount of quote vault shares used to convert to underlying.
    /// Pass 1 if the quote asset is not a vault. Should be chosen such that converting `quoteVaultConversionSample` to
    /// assets has enough precision.
    /// @param quoteFeed1 First quote feed. Pass address zero if the price = 1.
    /// @param quoteFeed2 Second quote feed. Pass address zero if the price = 1.
    /// @param quoteTokenDecimals Quote token decimals.
    /// @dev The base asset should be the collateral token and the quote asset the loan token.
    constructor(
        IERC4626 baseVault,
        uint256 baseVaultConversionSample,
        AggregatorV3Interface baseFeed1,
        AggregatorV3Interface baseFeed2,
        uint256 baseTokenDecimals,
        IERC4626 quoteVault,
        uint256 quoteVaultConversionSample,
        AggregatorV3Interface quoteFeed1,
        AggregatorV3Interface quoteFeed2,
        uint256 quoteTokenDecimals
    ) {
        // The ERC4626 vault parameters are used to price their respective conversion samples of their respective
        // shares, so it requires multiplying by `QUOTE_VAULT_CONVERSION_SAMPLE` and dividing
        // by `BASE_VAULT_CONVERSION_SAMPLE` in the `SCALE_FACTOR` definition.
        // Verify that vault = address(0) => vaultConversionSample = 1 for each vault.
        require(
            address(baseVault) != address(0) || baseVaultConversionSample == 1,
            ErrorsLib.VAULT_CONVERSION_SAMPLE_IS_NOT_ONE
        );
        require(
            address(quoteVault) != address(0) || quoteVaultConversionSample == 1,
            ErrorsLib.VAULT_CONVERSION_SAMPLE_IS_NOT_ONE
        );
        require(baseVaultConversionSample != 0, ErrorsLib.VAULT_CONVERSION_SAMPLE_IS_ZERO);
        require(quoteVaultConversionSample != 0, ErrorsLib.VAULT_CONVERSION_SAMPLE_IS_ZERO);

        BASE_VAULT = baseVault;
        BASE_VAULT_CONVERSION_SAMPLE = baseVaultConversionSample;
        QUOTE_VAULT = quoteVault;
        QUOTE_VAULT_CONVERSION_SAMPLE = quoteVaultConversionSample;
        BASE_FEED_1 = baseFeed1;
        BASE_FEED_2 = baseFeed2;
        QUOTE_FEED_1 = quoteFeed1;
        QUOTE_FEED_2 = quoteFeed2;

        // In the following comment, we explain the general case (where we assume that no feed is the address zero)
        // how to scale the output price as Morpho Blue expects, given the input feed prices.
        // Similar explanations would hold in the case where some of the feeds are the address zero.

        // Let B1, B2, Q1, Q2, C be 5 assets, each respectively having dB1, dB2, dQ1, dQ2, dC decimals.
        // Let pB1 and pB2 be the base prices, and pQ1 and pQ2 the quote prices, so that:
        // - pB1 is the quantity of 1e(dB2) assets B2 that can be exchanged for 1e(dB1) assets B1.
        // - pB2 is the quantity of 1e(dC) assets C that can be exchanged for 1e(dB2) assets B2.
        // - pQ1 is the quantity of 1e(dQ2) assets Q2 that can be exchanged for 1e(dQ1) assets Q1.
        // - pQ2 is the quantity of 1e(dC) assets C that can be exchanged for 1e(dQ2) assets B2.

        // Morpho Blue expects `price()` to be the quantity of 1 asset Q1 that can be exchanged for 1 asset B1,
        // scaled by 1e36:
        // 1e36 * (pB1 * 1e(dB2 - dB1)) * (pB2 * 1e(dC - dB2)) / ((pQ1 * 1e(dQ2 - dQ1)) * (pQ2 * 1e(dC - dQ2)))
        // = 1e36 * (pB1 * 1e(-dB1) * pB2) / (pQ1 * 1e(-dQ1) * pQ2)

        // Let fpB1, fpB2, fpQ1, fpQ2 be the feed precision of the respective prices pB1, pB2, pQ1, pQ2.
        // Feeds return pB1 * 1e(fpB1), pB2 * 1e(fpB2), pQ1 * 1e(fpQ1) and pQ2 * 1e(fpQ2).

        // Based on the implementation of `price()` below, the value of `SCALE_FACTOR` should thus satisfy:
        // (pB1 * 1e(fpB1)) * (pB2 * 1e(fpB2)) * SCALE_FACTOR / ((pQ1 * 1e(fpQ1)) * (pQ2 * 1e(fpQ2)))
        // = 1e36 * (pB1 * 1e(-dB1) * pB2) / (pQ1 * 1e(-dQ1) * pQ2)

        // So SCALE_FACTOR = 1e36 * 1e(-dB1) * 1e(dQ1) * 1e(-fpB1) * 1e(-fpB2) * 1e(fpQ1) * 1e(fpQ2)
        //                 = 1e(36 + dQ1 + fpQ1 + fpQ2 - dB1 - fpB1 - fpB2)
        SCALE_FACTOR = 10
            ** (
                36 + quoteTokenDecimals + quoteFeed1.getDecimals() + quoteFeed2.getDecimals() - baseTokenDecimals
                    - baseFeed1.getDecimals() - baseFeed2.getDecimals()
            ) * quoteVaultConversionSample / baseVaultConversionSample;
    }

    /* PRICE */

    /// @inheritdoc IOracle
    function price() external view returns (uint256) {
        return SCALE_FACTOR.mulDiv(
            BASE_VAULT.getAssets(BASE_VAULT_CONVERSION_SAMPLE) * BASE_FEED_1.getPrice() * BASE_FEED_2.getPrice(),
            QUOTE_VAULT.getAssets(QUOTE_VAULT_CONVERSION_SAMPLE) * QUOTE_FEED_1.getPrice() * QUOTE_FEED_2.getPrice()
        );
    }
}

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

interface IERC4626 {
    function convertToAssets(uint256) external view returns (uint256);
}

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

/// @title IOracle
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Interface that oracles used by Morpho must implement.
/// @dev It is the user's responsibility to select markets with safe oracles.
interface IOracle {
    /// @notice Returns the price of 1 asset of collateral token quoted in 1 asset of loan token, scaled by 1e36.
    /// @dev It corresponds to the price of 10**(collateral token decimals) assets of collateral token quoted in
    /// 10**(loan token decimals) assets of loan token with `36 + loan token decimals - collateral token decimals`
    /// decimals of precision.
    function price() external view returns (uint256);
}

File 9 of 11 : AggregatorV3Interface.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;

/// @dev From
/// https://github.com/smartcontractkit/chainlink/blob/master/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol
interface AggregatorV3Interface {
    function decimals() external view returns (uint8);

    function description() external view returns (string memory);

    function version() external view returns (uint256);

    function getRoundData(uint80 _roundId)
        external
        view
        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);

    function latestRoundData()
        external
        view
        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}

File 10 of 11 : ErrorsLib.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

/// @title ErrorsLib
/// @author Morpho Labs
/// @custom:contact [email protected]
/// @notice Library exposing error messages.
library ErrorsLib {
    /// @notice Thrown when the answer returned by a Chainlink feed is negative.
    string constant NEGATIVE_ANSWER = "negative answer";

    /// @notice Thrown when the vault conversion sample is 0.
    string constant VAULT_CONVERSION_SAMPLE_IS_ZERO = "vault conversion sample is zero";

    /// @notice Thrown when the vault conversion sample is not 1 while vault = address(0).
    string constant VAULT_CONVERSION_SAMPLE_IS_NOT_ONE = "vault conversion sample is not one";
}

File 11 of 11 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Muldiv operation overflow.
     */
    error MathOverflowedMulDiv();

    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            return a / b;
        }

        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
     * denominator == 0.
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
     * Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0 = x * y; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            if (denominator <= prod1) {
                revert MathOverflowedMulDiv();
            }

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.

            uint256 twos = denominator & (0 - denominator);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
            // works in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
     * towards zero.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
        }
    }

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "morpho-blue/=lib/morpho-blue/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 999999
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"address","name":"oracle","type":"address"}],"name":"CreateMorphoChainlinkOracleV2","type":"event"},{"inputs":[{"internalType":"contract IERC4626","name":"baseVault","type":"address"},{"internalType":"uint256","name":"baseVaultConversionSample","type":"uint256"},{"internalType":"contract AggregatorV3Interface","name":"baseFeed1","type":"address"},{"internalType":"contract AggregatorV3Interface","name":"baseFeed2","type":"address"},{"internalType":"uint256","name":"baseTokenDecimals","type":"uint256"},{"internalType":"contract IERC4626","name":"quoteVault","type":"address"},{"internalType":"uint256","name":"quoteVaultConversionSample","type":"uint256"},{"internalType":"contract AggregatorV3Interface","name":"quoteFeed1","type":"address"},{"internalType":"contract AggregatorV3Interface","name":"quoteFeed2","type":"address"},{"internalType":"uint256","name":"quoteTokenDecimals","type":"uint256"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"createMorphoChainlinkOracleV2","outputs":[{"internalType":"contract MorphoChainlinkOracleV2","name":"oracle","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isMorphoChainlinkOracleV2","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60808060405234610016576111c2908161001c8239f35b600080fdfe60806040818152600436101561001457600080fd5b600091823560e01c9081634cf4a26414610204575063b32cddf41461003857600080fd5b34610200576101607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102005760043573ffffffffffffffffffffffffffffffffffffffff908181168091036101fc576044358281168091036101f8576064358381168091036101f45760a4358481168091036101f05760e435908582168092036101ec5761010435928684168094036101e857875194610f1e968787019787891067ffffffffffffffff8a11176101bb5761026f883987526024356020880152888701526060860152608435608086015260a085015260c43560c085015260e08401526101008301526101243561012083015261014081610144359303019085f580156101af579180916020949316928381528085522060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008254161790557f6436acb89463dbc9036f1e52aebf32ac0bf5f69e3987c067110c3ac403ebda338180513381528486820152a151908152f35b505051903d90823e3d90fd5b60248c7f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b8880fd5b8780fd5b8680fd5b8580fd5b8480fd5b8380fd5b5080fd5b9190503461026a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261026a5760043573ffffffffffffffffffffffffffffffffffffffff81168091036101fc578352602083815292205460ff1615158152f35b8280fdfe6101a08060405234620002fa578062000f1e803803809162000022828562000331565b833961014092839181010312620002fa576200003e8162000355565b91602082015190620000536040840162000355565b90620000626060850162000355565b926080850151956200007760a0870162000355565b9060c0870151956200008c60e0890162000355565b95610100996200009e8b8b0162000355565b6101209a8b0151956001600160a01b0386811615801590620002ef575b620000d190620000ca6200036a565b90620003bf565b811615801590620002e4575b620000ec90620000ca6200036a565b8715956200015a6040516200010181620002ff565b601f8152620001397f7661756c7420636f6e76657273696f6e2073616d706c65206973207a65726f00918260208201528a15620003bf565b604051906200014882620002ff565b601f825260208201528d1515620003bf565b6080528760a05260c0528960e052828c52838b5288885261016098818a52602496870190818811620002cf57620001bd620001ca94620001c4620001bd95620001b6620001bd620001d19b9a97620001b6620001ca986200045b565b9062000429565b916200045b565b6200044d565b906200044d565b604d8111620002ba57600a0a868102968188041490151715620002a5576200029157506101809304835260405193610a269586620004f8873960805186818161014b0152610304015260a0518681816102e301526105b9015260c0518681816103ac0152610560015260e05186818161038b01526104f301525185818160d9015261032d0152518481816101b9015261035c0152518381816103d5015261049a01525182818161027f01526103fe01525181818161021201526104250152f35b634e487b7160e01b60009081526012600452fd5b50634e487b7160e01b60009081526011600452fd5b82634e487b7160e01b60005260116004526000fd5b87634e487b7160e01b60005260116004526000fd5b5060018b14620000dd565b5060018914620000bb565b600080fd5b604081019081106001600160401b038211176200031b57604052565b634e487b7160e01b600052604160045260246000fd5b601f909101601f19168101906001600160401b038211908210176200031b57604052565b51906001600160a01b0382168203620002fa57565b60405190606082016001600160401b038111838210176200031b5760405260228252616e6560f01b6040837f7661756c7420636f6e76657273696f6e2073616d706c65206973206e6f74206f60208201520152565b15620003c85750565b6040519062461bcd60e51b82528160208060048301528251908160248401526000935b8285106200040f575050604492506000838284010152601f80199101168101030190fd5b8481018201518686016044015293810193859350620003eb565b919082018092116200043757565b634e487b7160e01b600052601160045260246000fd5b919082039182116200043757565b6001600160a01b03168015620004f15760206004916040519283809263313ce56760e01b82525afa908115620004e5576000916200049b575b5060ff1690565b6020813d8211620004dc575b81620004b66020938362000331565b81010312620004d857519060ff82168203620004d5575060ff62000494565b80fd5b5080fd5b3d9150620004a7565b6040513d6000823e3d90fd5b5060009056fe60806040818152600436101561001457600080fd5b600091823560e01c908163054f7ac014610584575080632e6f20a614610516578063461739d2146104be57806356095e1114610450578063a035b1fe146102a3578063acfbd39e14610235578063ce4b5bbe146101dd578063dc53858c1461016f578063eaa2d7b4146101015763f50a47181461009057600080fd5b346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5080fd5b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd57602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020906104496103806103576103287f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061094a565b6103517f00000000000000000000000000000000000000000000000000000000000000006107a5565b906105dc565b6103517f00000000000000000000000000000000000000000000000000000000000000006107a5565b6104226103f96103d07f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061094a565b6103517f00000000000000000000000000000000000000000000000000000000000000006107a5565b6103517f00000000000000000000000000000000000000000000000000000000000000006107a5565b907f000000000000000000000000000000000000000000000000000000000000000061061e565b9051908152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd57602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b8390346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020907f00000000000000000000000000000000000000000000000000000000000000008152f35b818102929181159184041417156105ef57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9091828202917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848209938380861095039480860395146106dc57848311156106b25782910981600003821680920460028082600302188083028203028083028203028083028203028083028203028083028203028092029003029360018380600003040190848311900302920304170290565b60046040517f227bc153000000000000000000000000000000000000000000000000000000008152fd5b5050809250156106ea570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761075a57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b519069ffffffffffffffffffff821682036107a057565b600080fd5b73ffffffffffffffffffffffffffffffffffffffff1680156109445760049060a06040918251938480927ffeaf968c0000000000000000000000000000000000000000000000000000000082525afa918215610939576000926108e8575b50805181810181811067ffffffffffffffff82111761075a578252600f81526020917f6e6567617469766520616e73776572000000000000000000000000000000000083830152600084126108585750505090565b5180927f08c379a000000000000000000000000000000000000000000000000000000000825280600483015282519283602484015260005b8481106108d1575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f836000604480968601015201168101030190fd5b818101830151868201604401528593508201610890565b909160a0823d8211610931575b8161090260a09383610719565b8101031261092e575061091481610789565b50610926608060208301519201610789565b509038610803565b80fd5b3d91506108f5565b50513d6000823e3d90fd5b50600190565b73ffffffffffffffffffffffffffffffffffffffff169081156109e9576020906024604051809481937f07a2d13a00000000000000000000000000000000000000000000000000000000835260048301525afa9081156109dd576000916109af575090565b906020823d82116109d5575b816109c860209383610719565b8101031261092e57505190565b3d91506109bb565b6040513d6000823e3d90fd5b505060019056fea2646970667358221220de25ff8dd5708a691db44b0da1e6e734e7659c3f9a1801595bc1fa7bf902c00564736f6c63430008150033a264697066735822122015409f1c8f72cb8a987928512dada6208613a59c2474a64090988bff363999f464736f6c63430008150033

Deployed Bytecode

0x60806040818152600436101561001457600080fd5b600091823560e01c9081634cf4a26414610204575063b32cddf41461003857600080fd5b34610200576101607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126102005760043573ffffffffffffffffffffffffffffffffffffffff908181168091036101fc576044358281168091036101f8576064358381168091036101f45760a4358481168091036101f05760e435908582168092036101ec5761010435928684168094036101e857875194610f1e968787019787891067ffffffffffffffff8a11176101bb5761026f883987526024356020880152888701526060860152608435608086015260a085015260c43560c085015260e08401526101008301526101243561012083015261014081610144359303019085f580156101af579180916020949316928381528085522060017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008254161790557f6436acb89463dbc9036f1e52aebf32ac0bf5f69e3987c067110c3ac403ebda338180513381528486820152a151908152f35b505051903d90823e3d90fd5b60248c7f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b8880fd5b8780fd5b8680fd5b8580fd5b8480fd5b8380fd5b5080fd5b9190503461026a5760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261026a5760043573ffffffffffffffffffffffffffffffffffffffff81168091036101fc578352602083815292205460ff1615158152f35b8280fdfe6101a08060405234620002fa578062000f1e803803809162000022828562000331565b833961014092839181010312620002fa576200003e8162000355565b91602082015190620000536040840162000355565b90620000626060850162000355565b926080850151956200007760a0870162000355565b9060c0870151956200008c60e0890162000355565b95610100996200009e8b8b0162000355565b6101209a8b0151956001600160a01b0386811615801590620002ef575b620000d190620000ca6200036a565b90620003bf565b811615801590620002e4575b620000ec90620000ca6200036a565b8715956200015a6040516200010181620002ff565b601f8152620001397f7661756c7420636f6e76657273696f6e2073616d706c65206973207a65726f00918260208201528a15620003bf565b604051906200014882620002ff565b601f825260208201528d1515620003bf565b6080528760a05260c0528960e052828c52838b5288885261016098818a52602496870190818811620002cf57620001bd620001ca94620001c4620001bd95620001b6620001bd620001d19b9a97620001b6620001ca986200045b565b9062000429565b916200045b565b6200044d565b906200044d565b604d8111620002ba57600a0a868102968188041490151715620002a5576200029157506101809304835260405193610a269586620004f8873960805186818161014b0152610304015260a0518681816102e301526105b9015260c0518681816103ac0152610560015260e05186818161038b01526104f301525185818160d9015261032d0152518481816101b9015261035c0152518381816103d5015261049a01525182818161027f01526103fe01525181818161021201526104250152f35b634e487b7160e01b60009081526012600452fd5b50634e487b7160e01b60009081526011600452fd5b82634e487b7160e01b60005260116004526000fd5b87634e487b7160e01b60005260116004526000fd5b5060018b14620000dd565b5060018914620000bb565b600080fd5b604081019081106001600160401b038211176200031b57604052565b634e487b7160e01b600052604160045260246000fd5b601f909101601f19168101906001600160401b038211908210176200031b57604052565b51906001600160a01b0382168203620002fa57565b60405190606082016001600160401b038111838210176200031b5760405260228252616e6560f01b6040837f7661756c7420636f6e76657273696f6e2073616d706c65206973206e6f74206f60208201520152565b15620003c85750565b6040519062461bcd60e51b82528160208060048301528251908160248401526000935b8285106200040f575050604492506000838284010152601f80199101168101030190fd5b8481018201518686016044015293810193859350620003eb565b919082018092116200043757565b634e487b7160e01b600052601160045260246000fd5b919082039182116200043757565b6001600160a01b03168015620004f15760206004916040519283809263313ce56760e01b82525afa908115620004e5576000916200049b575b5060ff1690565b6020813d8211620004dc575b81620004b66020938362000331565b81010312620004d857519060ff82168203620004d5575060ff62000494565b80fd5b5080fd5b3d9150620004a7565b6040513d6000823e3d90fd5b5060009056fe60806040818152600436101561001457600080fd5b600091823560e01c908163054f7ac014610584575080632e6f20a614610516578063461739d2146104be57806356095e1114610450578063a035b1fe146102a3578063acfbd39e14610235578063ce4b5bbe146101dd578063dc53858c1461016f578063eaa2d7b4146101015763f50a47181461009057600080fd5b346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b5080fd5b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd57602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020906104496103806103576103287f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061094a565b6103517f00000000000000000000000000000000000000000000000000000000000000006107a5565b906105dc565b6103517f00000000000000000000000000000000000000000000000000000000000000006107a5565b6104226103f96103d07f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061094a565b6103517f00000000000000000000000000000000000000000000000000000000000000006107a5565b6103517f00000000000000000000000000000000000000000000000000000000000000006107a5565b907f000000000000000000000000000000000000000000000000000000000000000061061e565b9051908152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd57602090517f00000000000000000000000000000000000000000000000000000000000000008152f35b50346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b8390346100fd57817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126100fd576020907f00000000000000000000000000000000000000000000000000000000000000008152f35b818102929181159184041417156105ef57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9091828202917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848209938380861095039480860395146106dc57848311156106b25782910981600003821680920460028082600302188083028203028083028203028083028203028083028203028083028203028092029003029360018380600003040190848311900302920304170290565b60046040517f227bc153000000000000000000000000000000000000000000000000000000008152fd5b5050809250156106ea570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761075a57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b519069ffffffffffffffffffff821682036107a057565b600080fd5b73ffffffffffffffffffffffffffffffffffffffff1680156109445760049060a06040918251938480927ffeaf968c0000000000000000000000000000000000000000000000000000000082525afa918215610939576000926108e8575b50805181810181811067ffffffffffffffff82111761075a578252600f81526020917f6e6567617469766520616e73776572000000000000000000000000000000000083830152600084126108585750505090565b5180927f08c379a000000000000000000000000000000000000000000000000000000000825280600483015282519283602484015260005b8481106108d1575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f836000604480968601015201168101030190fd5b818101830151868201604401528593508201610890565b909160a0823d8211610931575b8161090260a09383610719565b8101031261092e575061091481610789565b50610926608060208301519201610789565b509038610803565b80fd5b3d91506108f5565b50513d6000823e3d90fd5b50600190565b73ffffffffffffffffffffffffffffffffffffffff169081156109e9576020906024604051809481937f07a2d13a00000000000000000000000000000000000000000000000000000000835260048301525afa9081156109dd576000916109af575090565b906020823d82116109d5575b816109c860209383610719565b8101031261092e57505190565b3d91506109bb565b6040513d6000823e3d90fd5b505060019056fea2646970667358221220de25ff8dd5708a691db44b0da1e6e734e7659c3f9a1801595bc1fa7bf902c00564736f6c63430008150033a264697066735822122015409f1c8f72cb8a987928512dada6208613a59c2474a64090988bff363999f464736f6c63430008150033

Deployed Bytecode Sourcemap

660:1280:3:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1465:332;;;;;;;;;;;;;;;;;;;660:1280;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1465:332;;;;;;;;;;660:1280;;;;;;;;;;;;;;;;;;;;;;;1873:58;660:1280;;;1903:10;660:1280;;;;;;;1873:58;660:1280;;;;;1465:332;660:1280;;;;;;;;;;;1465:332;660:1280;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

ipfs://15409f1c8f72cb8a987928512dada6208613a59c2474a64090988bff363999f4

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
[ Download: CSV Export  ]
[ 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.