Overview
ETH Balance
ETH Value
$0.00Multichain Info
Latest 1 from a total of 1 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Deploy Meta Orac... | 13721577 | 14 days ago | IN | 0 ETH | 0.00000166 |
Latest 2 internal transactions
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 13721577 | 14 days ago | Contract Creation | 0 ETH | |||
| 13721304 | 14 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {MetaOracleDeviationTimelock} from "./MetaOracleDeviationTimelock.sol";
import {IMetaOracleDeviationTimelock} from "./interfaces/IMetaOracleDeviationTimelock.sol";
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {IOracle} from "./interfaces/IOracle.sol";
/// @title MetaOracleDeviationTimelockFactory
/// @author Steakhouse Financial
/// @notice Factory for deploying MetaOracleDeviationTimelock instances using EIP-1167 proxies.
contract MetaOracleDeviationTimelockFactory {
address public immutable implementation;
event MetaOracleDeployed(
address indexed metaOracleAddress,
address implementationAddress,
address indexed primaryOracle,
address indexed backupOracle,
uint256 deviationThreshold,
uint256 challengeTimelockDuration,
uint256 healingTimelockDuration
);
constructor() {
implementation = address(new MetaOracleDeviationTimelock());
}
/// @notice Deploys a new MetaOracleDeviationTimelock proxy contract and initializes it.
/// @param _primaryOracle The primary price feed address.
/// @param _backupOracle The backup price feed address.
/// @param _deviationThreshold The max relative deviation (1e18 scale).
/// @param _challengeTimelockDuration Duration (seconds) before challenge can be accepted.
/// @param _healingTimelockDuration Duration (seconds) before healing can be accepted.
/// @return proxyInstance The interface of the newly deployed MetaOracleDeviationTimelock proxy contract.
function deployMetaOracle(
IOracle _primaryOracle,
IOracle _backupOracle,
uint256 _deviationThreshold,
uint256 _challengeTimelockDuration,
uint256 _healingTimelockDuration
) external returns (IMetaOracleDeviationTimelock proxyInstance) {
address proxy = Clones.clone(implementation);
proxyInstance = IMetaOracleDeviationTimelock(proxy);
// Initialize the proxy
MetaOracleDeviationTimelock(proxy).initialize(
_primaryOracle,
_backupOracle,
_deviationThreshold,
_challengeTimelockDuration,
_healingTimelockDuration
);
emit MetaOracleDeployed(
address(proxyInstance),
implementation,
address(_primaryOracle),
address(_backupOracle),
_deviationThreshold,
_challengeTimelockDuration,
_healingTimelockDuration
);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import {IMetaOracleDeviationTimelock} from "./interfaces/IMetaOracleDeviationTimelock.sol";
import {IOracle} from "./interfaces/IOracle.sol";
/// @title MetaOracleDeviationTimelock
/// @author Steakhouse Financial
/// @notice A meta-oracle that selects between a primary and backup oracle based on price deviation and timelocks.
/// @dev Switches to backup if primary deviates significantly, switches back when prices reconverge.
/// MUST be initialized by calling the `initialize` function.
contract MetaOracleDeviationTimelock is IMetaOracleDeviationTimelock, Initializable {
// --- Configuration (set during initialization) ---
IOracle public primaryOracle;
IOracle public backupOracle;
uint256 public deviationThreshold; // Scaled by 1e18 (e.g., 0.01e18 for 1%)
uint256 public challengeTimelockDuration; // Duration in seconds
uint256 public healingTimelockDuration; // Duration in seconds
// --- State ---
IOracle public currentOracle; // Currently selected oracle
uint256 public challengeExpiresAt; // Timestamp when challenge period ends (0 if not challenged)
uint256 public healingExpiresAt; // Timestamp when healing period ends (0 if not healing)
/// @param _primaryOracle The primary price feed.
/// @param _backupOracle The backup price feed.
/// @param _deviationThreshold The maximum allowed relative deviation (scaled by 1e18) before a challenge can be initiated.
/// @param _challengeTimelockDuration The duration (seconds) a challenge must persist before switching to backup.
/// @param _healingTimelockDuration The duration (seconds) prices must remain converged before switching back to primary.
function initialize(
IOracle _primaryOracle,
IOracle _backupOracle,
uint256 _deviationThreshold,
uint256 _challengeTimelockDuration,
uint256 _healingTimelockDuration
) external initializer {
require(address(_primaryOracle) != address(0), "Invalid primary oracle");
require(address(_backupOracle) != address(0), "Invalid backup oracle");
require(address(_primaryOracle) != address(_backupOracle), "Oracles must be different");
require(_deviationThreshold > 0, "Deviation threshold must be positive");
primaryOracle = _primaryOracle;
backupOracle = _backupOracle;
deviationThreshold = _deviationThreshold;
challengeTimelockDuration = _challengeTimelockDuration;
healingTimelockDuration = _healingTimelockDuration;
// Check initial deviation
uint256 initialDeviation = getDeviation();
require(initialDeviation <= _deviationThreshold, "MODT: Initial deviation too high");
currentOracle = _primaryOracle; // Start with the primary oracle
challengeExpiresAt = 0;
healingExpiresAt = 0;
}
/// @inheritdoc IOracle
function price() public view returns (uint256) {
try currentOracle.price() returns (uint256 currentPrice) {
return currentPrice;
} catch {
if (isPrimary()) {
return backupOracle.price();
} else {
return primaryOracle.price();
}
}
}
/// @inheritdoc IMetaOracleDeviationTimelock
function primaryPrice() public view returns (uint256) {
return primaryOracle.price();
}
/// @inheritdoc IMetaOracleDeviationTimelock
function backupPrice() public view returns (uint256) {
return backupOracle.price();
}
/// @notice Checks if the primary oracle is currently selected.
function isPrimary() public view returns (bool) {
return currentOracle == primaryOracle;
}
/// @notice Checks if the backup oracle is currently selected.
function isBackup() public view returns (bool) {
return currentOracle == backupOracle;
}
/// @notice Checks if a challenge is currently active.
function isChallenged() public view returns (bool) {
return challengeExpiresAt > 0;
}
/// @notice Checks if a healing period is currently active.
function isHealing() public view returns (bool) {
return healingExpiresAt > 0;
}
/// @notice Calculates the absolute relative deviation between primary and backup oracles.
/// @dev Deviation is calculated as `abs(primaryPrice - backupPrice) * 1e18 / average(primaryPrice, backupPrice)`.
/// Returns 0 if both prices are 0.
function getDeviation() public view returns (uint256) {
uint256 currentPrimaryPrice = primaryOracle.price();
uint256 currentBackupPrice = backupOracle.price();
// Handle case where both prices are zero
if (currentPrimaryPrice == 0 && currentBackupPrice == 0) {
return 0;
}
uint256 diff;
if (currentPrimaryPrice >= currentBackupPrice) {
diff = currentPrimaryPrice - currentBackupPrice;
} else {
diff = currentBackupPrice - currentPrimaryPrice;
}
// Calculate average of the two prices
uint256 average = (currentPrimaryPrice + currentBackupPrice) / 2;
// Use uint256 for intermediate multiplication to avoid overflow before division
return (diff * 10**18) / average;
}
/// @notice Checks if the deviation exceeds the configured threshold.
function isDeviant() public view returns (bool) {
return getDeviation() > deviationThreshold;
}
/// @notice Initiates a challenge if the primary oracle is active and deviation threshold is exceeded.
/// @dev Starts a timelock period (`challengeTimelockDuration`).
function challenge() external {
require(isPrimary(), "MODT: Must be primary oracle");
require(!isChallenged(), "MODT: Already challenged");
require(isDeviant(), "MODT: Deviation threshold not met");
challengeExpiresAt = block.timestamp + challengeTimelockDuration;
emit ChallengeStarted(challengeExpiresAt);
}
/// @notice Revokes an active challenge if the deviation is no longer present.
function revokeChallenge() external {
require(isPrimary(), "MODT: Must be primary oracle"); // Should still be primary
require(isChallenged(), "MODT: Not challenged");
require(!isDeviant(), "MODT: Deviation threshold still met");
challengeExpiresAt = 0;
emit ChallengeRevoked();
}
/// @notice Checks if the challenge has expired.
function hasChallengeExpired() public view returns (bool) {
return isChallenged() && block.timestamp >= challengeExpiresAt;
}
/// @notice Checks if the challenge can be accepted.
function canAcceptChallenge() public view returns (bool) {
return isPrimary() && isChallenged() && block.timestamp >= challengeExpiresAt && isDeviant();
}
/// @notice Accepts the challenge after the timelock expires, switching to the backup oracle.
/// @dev Requires the deviation to still be present.
function acceptChallenge() external {
require(isPrimary(), "MODT: Must be primary oracle");
require(isChallenged(), "MODT: Not challenged");
require(block.timestamp >= challengeExpiresAt, "MODT: Challenge timelock not passed");
require(isDeviant(), "MODT: Deviation resolved"); // Deviation must persist
currentOracle = backupOracle;
challengeExpiresAt = 0;
emit ChallengeAccepted(address(currentOracle));
}
/// @notice Initiates the healing process if the backup oracle is active and prices have reconverged.
/// @dev Starts a timelock period (`healingTimelockDuration`).
function heal() external {
require(isBackup(), "MODT: Must be backup oracle");
require(!isHealing(), "MODT: Already healing");
require(!isDeviant(), "MODT: Deviation threshold still met");
healingExpiresAt = block.timestamp + healingTimelockDuration;
emit HealingStarted(healingExpiresAt);
}
/// @notice Revokes an active healing process if the deviation threshold is exceeded again.
function revokeHealing() external {
require(isBackup(), "MODT: Must be backup oracle"); // Should still be backup
require(isHealing(), "MODT: Not healing");
require(isDeviant(), "MODT: Deviation threshold not met");
healingExpiresAt = 0;
emit HealingRevoked();
}
/// @notice Checks if the healing has expired.
function hasHealingExpired() public view returns (bool) {
return isHealing() && block.timestamp >= healingExpiresAt;
}
/// @notice Checks if the healing can be accepted.
function canAcceptHealing() public view returns (bool) {
return isBackup() && isHealing() && block.timestamp >= healingExpiresAt && !isDeviant();
}
/// @notice Accepts the healing after the timelock expires, switching back to the primary oracle.
/// @dev Requires the prices to still be converged (not deviant).
function acceptHealing() external {
require(isBackup(), "MODT: Must be backup oracle");
require(isHealing(), "MODT: Not healing");
require(block.timestamp >= healingExpiresAt, "MODT: Healing timelock not passed");
require(!isDeviant(), "MODT: Deviation occurred"); // Prices must remain converged
currentOracle = primaryOracle;
healingExpiresAt = 0;
emit HealingAccepted(address(currentOracle));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IOracle} from "./IOracle.sol";
/// @title IMetaOracleDeviationTimelock
/// @notice Interface for the MetaOracleDeviationTimelock contract, extending IOracle.
interface IMetaOracleDeviationTimelock is IOracle {
// --- Events (Mirroring implementation) ---
event ChallengeStarted(uint256 expiresAt);
event ChallengeRevoked();
event ChallengeAccepted(address indexed newOracle);
event HealingStarted(uint256 expiresAt);
event HealingRevoked();
event HealingAccepted(address indexed newOracle);
// --- Configuration --- Accessors for state variables set during initialization
function primaryOracle() external view returns (IOracle);
function backupOracle() external view returns (IOracle);
function primaryPrice() external view returns (uint256);
function backupPrice() external view returns (uint256);
function deviationThreshold() external view returns (uint256);
function challengeTimelockDuration() external view returns (uint256);
function healingTimelockDuration() external view returns (uint256);
// --- State --- Accessors for dynamic state variables
function currentOracle() external view returns (IOracle);
function challengeExpiresAt() external view returns (uint256);
function healingExpiresAt() external view returns (uint256);
// --- Views ---
function isPrimary() external view returns (bool);
function isBackup() external view returns (bool);
function isChallenged() external view returns (bool);
function isHealing() external view returns (bool);
function getDeviation() external view returns (uint256);
function isDeviant() external view returns (bool);
function hasChallengeExpired() external view returns (bool);
function hasHealingExpired() external view returns (bool);
function canAcceptChallenge() external view returns (bool);
function canAcceptHealing() external view returns (bool);
// --- State Changing Functions ---
function challenge() external;
function revokeChallenge() external;
function acceptChallenge() external;
function heal() external;
function revokeHealing() external;
function acceptHealing() external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/Clones.sol)
pragma solidity ^0.8.20;
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*/
library Clones {
/**
* @dev A clone instance deployment failed.
*/
error ERC1167FailedCreateClone();
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create(0, 0x09, 0x37)
}
if (instance == address(0)) {
revert ERC1167FailedCreateClone();
}
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple time will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create2(0, 0x09, 0x37, salt)
}
if (instance == address(0)) {
revert ERC1167FailedCreateClone();
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(add(ptr, 0x38), deployer)
mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
mstore(add(ptr, 0x14), implementation)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
mstore(add(ptr, 0x58), salt)
mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
predicted := keccak256(add(ptr, 0x43), 0x55)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt
) internal view returns (address predicted) {
return predictDeterministicAddress(implementation, salt, address(this));
}
}// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /// @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); }
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"ds-auth/=lib/dss-psm/lib/dss/lib/ds-token/lib/ds-auth/src/",
"ds-math/=lib/dss-psm/lib/dss/lib/ds-token/lib/ds-math/src/",
"ds-note/=lib/dss-psm/lib/dss/lib/ds-value/lib/ds-thing/lib/ds-note/src/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"ds-thing/=lib/dss-psm/lib/dss/lib/ds-value/lib/ds-thing/src/",
"ds-token/=lib/dss-psm/lib/dss/lib/ds-token/src/",
"ds-value/=lib/dss-psm/lib/dss/lib/ds-value/src/",
"dss-interfaces/=lib/dss-psm/lib/dss-interfaces/src/",
"dss-psm/=lib/dss-psm/src/",
"dss/=lib/dss-psm/lib/dss/src/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"morpho-blue-oracles/=lib/morpho-blue-oracles/src/",
"@morpho-blue-oracles/=lib/morpho-blue-oracles/",
"morpho-blue/=lib/morpho-blue/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
"@uniswap/v3-periphery/=lib/v3-periphery/",
"@uniswap/v3-core/=lib/v3-core/",
"@pendle-core-v2/=lib/pendle-core-v2-public/contracts/",
"@slipstream/contracts/=lib/slipstream/contracts/",
"@ensdomains/=lib/slipstream/node_modules/@ensdomains/",
"@nomad-xyz/=lib/slipstream/lib/ExcessivelySafeCall/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@solidity-parser/=lib/slipstream/node_modules/solhint/node_modules/@solidity-parser/",
"ExcessivelySafeCall/=lib/slipstream/lib/ExcessivelySafeCall/src/",
"base64-sol/=lib/slipstream/lib/base64/",
"base64/=lib/slipstream/lib/base64/",
"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"hardhat/=lib/slipstream/node_modules/hardhat/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"pendle-core-v2-public/=lib/pendle-core-v2-public/contracts/",
"slipstream/=lib/slipstream/",
"solidity-lib/=lib/slipstream/lib/solidity-lib/contracts/",
"steakhouse-oracles/=lib/steakhouse-oracles/src/",
"v3-core/=lib/v3-core/",
"v3-periphery/=lib/v3-periphery/contracts/"
],
"optimizer": {
"enabled": false,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "shanghai",
"viaIR": true
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ERC1167FailedCreateClone","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"metaOracleAddress","type":"address"},{"indexed":false,"internalType":"address","name":"implementationAddress","type":"address"},{"indexed":true,"internalType":"address","name":"primaryOracle","type":"address"},{"indexed":true,"internalType":"address","name":"backupOracle","type":"address"},{"indexed":false,"internalType":"uint256","name":"deviationThreshold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"challengeTimelockDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"healingTimelockDuration","type":"uint256"}],"name":"MetaOracleDeployed","type":"event"},{"inputs":[{"internalType":"contract IOracle","name":"_primaryOracle","type":"address"},{"internalType":"contract IOracle","name":"_backupOracle","type":"address"},{"internalType":"uint256","name":"_deviationThreshold","type":"uint256"},{"internalType":"uint256","name":"_challengeTimelockDuration","type":"uint256"},{"internalType":"uint256","name":"_healingTimelockDuration","type":"uint256"}],"name":"deployMetaOracle","outputs":[{"internalType":"contract IMetaOracleDeviationTimelock","name":"proxyInstance","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a06040523461003d576100116100b7565b610019610042565b61060461010a82396080518181816061015281816103b10152610454015261060490f35b610048565b60405190565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b5f0190565b61006d610042565b3d5f823e3d90fd5b60018060a01b031690565b90565b61009761009261009c92610075565b610080565b610075565b90565b6100a890610083565b90565b6100b49061009f565b90565b6100bf610042565b6125c8810181811060018060401b03821117610104576100e782916125c861070e8439610060565b03905ff080156100ff576100fa906100ab565b608052565b610065565b61004c56fe60806040526004361015610013575b61022e565b61001d5f3561003c565b80635c60da1b146100375763f3afc37b0361000e576101f5565b6100bc565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f91031261005a57565b61004c565b7f000000000000000000000000000000000000000000000000000000000000000090565b60018060a01b031690565b61009790610083565b90565b6100a39061008e565b9052565b91906100ba905f6020850194019061009a565b565b346100ec576100cc366004610050565b6100e86100d761005f565b6100df610042565b918291826100a7565b0390f35b610048565b6100fa9061008e565b90565b610106816100f1565b0361010d57565b5f80fd5b9050359061011e826100fd565b565b90565b61012c81610120565b0361013357565b5f80fd5b9050359061014482610123565b565b919060a0838203126101975761015e815f8501610111565b9261016c8260208301610111565b9261019461017d8460408501610137565b9361018b8160608601610137565b93608001610137565b90565b61004c565b90565b6101b36101ae6101b892610083565b61019c565b610083565b90565b6101c49061019f565b90565b6101d0906101bb565b90565b6101dc906101c7565b9052565b91906101f3905f602085019401906101d3565b565b346102295761022561021461020b366004610146565b9392909261039f565b61021c610042565b918291826101e0565b0390f35b610048565b5f80fd5b5f90565b61023f9061019f565b90565b61024b90610236565b90565b6102579061019f565b90565b6102639061024e565b90565b61026f906101bb565b90565b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b9061029e90610276565b810190811067ffffffffffffffff8211176102b857604052565b610280565b60e01b90565b5f9103126102cd57565b61004c565b6102db906101bb565b90565b6102e7906102d2565b9052565b6102f490610120565b9052565b909594926103439461033261033c9261032860809661031e60a088019c5f8901906102de565b60208701906102de565b60408501906102eb565b60608301906102eb565b01906102eb565b565b61034d610042565b3d5f823e3d90fd5b61035e906101bb565b90565b61039661039d9461038c606094989795610382608086019a5f87019061009a565b60208501906102eb565b60408301906102eb565b01906102eb565b565b949392946103ab610232565b506103d57f000000000000000000000000000000000000000000000000000000000000000061053f565b956103f06103eb6103e589610242565b9861025a565b610266565b63d13f90b48385928792858a91833b156105065761042f610424935f97938894610418610042565b9a8b998a9889976102bd565b8752600487016102f8565b03925af18015610501576104d5575b50610448876101c7565b916104d061047f6104797f0000000000000000000000000000000000000000000000000000000000000000936102d2565b956102d2565b9592966104be6104b86104b27fff56edf5f37154a80711a8b72abc534ce41632b43d407c139574fe8850c65ce997610355565b97610355565b97610355565b976104c7610042565b94859485610361565b0390a4565b6104f4905f3d81116104fa575b6104ec8183610294565b8101906102c3565b5f61043e565b503d6104e2565b610345565b610272565b5f90565b90565b61052661052161052b9261050f565b61019c565b610083565b90565b61053790610512565b90565b5f0190565b6e5af43d82803e903d91602b57fd5bf39061055861050b565b50763d602d80600a3d3981f3363d3d373d3d3d363d730000008160601b60e81c175f5260781b17602052603760095ff090816105a461059e6105995f61052e565b61008e565b9161008e565b146105ab57565b6105b3610042565b6330be1a3d60e21b8152806105ca6004820161053a565b0390fdfea2646970667358221220722f68207d7be3ca02688b263ded68b06557b5fd350d2e5bc462945df20dd06964736f6c6343000815003360806040523461001f57610011610024565b61259961002f823961259990f35b61002a565b60405190565b5f80fdfe60806040526004361015610013575b6109fd565b61001d5f356101db565b8062372f87146101d657806303c01e68146101d15780630434fe0b146101cc5780631fc08644146101c7578063219a94b8146101c25780632289445e146101bd5780632f0a577b146101b8578063362a07ae146101b35780633682152b146101ae578063498e8b6e146101a95780637ad6d6d5146101a4578063836efd311461019f57806389ab35321461019a5780639df4d0fe14610195578063a035b1fe14610190578063ad8910061461018b578063b166bf6b14610186578063bd8f238e14610181578063c2ee5df91461017c578063ccc1b9cd14610177578063d13f90b414610172578063d2ef73981461016d578063d83ed44014610168578063d94ad83714610163578063de1a69751461015e578063e2997d6b14610159578063f8f8b5f0146101545763f9e344470361000e576109c8565b610984565b610951565b61091c565b6108e7565b6108a3565b610861565b61082a565b610741565b6106fd565b6106c8565b610688565b610653565b61061e565b6105e9565b6105b4565b61057f565b61053b565b610506565b610499565b610464565b61040a565b6103d5565b6102fa565b6102c5565b610292565b61025d565b610203565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f9103126101f957565b6101eb565b5f0190565b34610231576102133660046101ef565b61021b612238565b6102236101e1565b8061022d816101fe565b0390f35b6101e7565b151590565b61024490610236565b9052565b919061025b905f6020850194019061023b565b565b3461028d5761026d3660046101ef565b6102896102786115b7565b6102806101e1565b91829182610248565b0390f35b6101e7565b346102c0576102a23660046101ef565b6102aa612111565b6102b26101e1565b806102bc816101fe565b0390f35b6101e7565b346102f5576102d53660046101ef565b6102f16102e0611da0565b6102e86101e1565b91829182610248565b0390f35b6101e7565b346103285761030a3660046101ef565b61031261248a565b61031a6101e1565b80610324816101fe565b0390f35b6101e7565b1c90565b60018060a01b031690565b61034c906008610351930261032d565b610331565b90565b9061035f915461033c565b90565b61036e60055f90610354565b90565b60018060a01b031690565b90565b61039361038e61039892610371565b61037c565b610371565b90565b6103a49061037f565b90565b6103b09061039b565b90565b6103bc906103a7565b9052565b91906103d3905f602085019401906103b3565b565b34610405576103e53660046101ef565b6104016103f0610362565b6103f86101e1565b918291826103c0565b0390f35b6101e7565b3461043a5761041a3660046101ef565b610436610425611d62565b61042d6101e1565b91829182610248565b0390f35b6101e7565b90565b61044b9061043f565b9052565b9190610462905f60208501940190610442565b565b34610494576104743660046101ef565b61049061047f611465565b6104876101e1565b9182918261044f565b0390f35b6101e7565b346104c9576104a93660046101ef565b6104c56104b4611586565b6104bc6101e1565b91829182610248565b0390f35b6101e7565b90565b6104e19060086104e6930261032d565b6104ce565b90565b906104f491546104d1565b90565b61050360035f906104e9565b90565b34610536576105163660046101ef565b6105326105216104f7565b6105296101e1565b9182918261044f565b0390f35b6101e7565b3461056b5761054b3660046101ef565b6105676105566122f1565b61055e6101e1565b91829182610248565b0390f35b6101e7565b61057c60015f90610354565b90565b346105af5761058f3660046101ef565b6105ab61059a610570565b6105a26101e1565b918291826103c0565b0390f35b6101e7565b346105e4576105c43660046101ef565b6105e06105cf611763565b6105d76101e1565b9182918261044f565b0390f35b6101e7565b34610619576105f93660046101ef565b61061561060461160a565b61060c6101e1565b91829182610248565b0390f35b6101e7565b3461064e5761062e3660046101ef565b61064a6106396112b0565b6106416101e1565b9182918261044f565b0390f35b6101e7565b34610683576106633660046101ef565b61067f61066e6114f3565b6106766101e1565b9182918261044f565b0390f35b6101e7565b346106b6576106983660046101ef565b6106a0611f3c565b6106a86101e1565b806106b2816101fe565b0390f35b6101e7565b6106c55f80610354565b90565b346106f8576106d83660046101ef565b6106f46106e36106bb565b6106eb6101e1565b918291826103c0565b0390f35b6101e7565b3461072d5761070d3660046101ef565b6107296107186122b3565b6107206101e1565b91829182610248565b0390f35b6101e7565b61073e60065f906104e9565b90565b34610771576107513660046101ef565b61076d61075c610732565b6107646101e1565b9182918261044f565b0390f35b6101e7565b61077f90610371565b90565b61078b90610776565b90565b61079781610782565b0361079e57565b5f80fd5b905035906107af8261078e565b565b6107ba8161043f565b036107c157565b5f80fd5b905035906107d2826107b1565b565b919060a083820312610825576107ec815f85016107a2565b926107fa82602083016107a2565b9261082261080b84604085016107c5565b9361081981606086016107c5565b936080016107c5565b90565b6101eb565b3461085c5761084661083d3660046107d4565b939290926111ce565b61084e6101e1565b80610858816101fe565b0390f35b6101e7565b3461088f576108713660046101ef565b610879611b18565b6108816101e1565b8061088b816101fe565b0390f35b6101e7565b6108a060045f906104e9565b90565b346108d3576108b33660046101ef565b6108cf6108be610894565b6108c66101e1565b9182918261044f565b0390f35b6101e7565b6108e460025f906104e9565b90565b34610917576108f73660046101ef565b6109136109026108d8565b61090a6101e1565b9182918261044f565b0390f35b6101e7565b3461094c5761092c3660046101ef565b61094861093761193c565b61093f6101e1565b91829182610248565b0390f35b6101e7565b3461097f576109613660046101ef565b610969611cde565b6109716101e1565b8061097b816101fe565b0390f35b6101e7565b346109b4576109943660046101ef565b6109b061099f611633565b6109a76101e1565b91829182610248565b0390f35b6101e7565b6109c560075f906104e9565b90565b346109f8576109d83660046101ef565b6109f46109e36109b9565b6109eb6101e1565b9182918261044f565b0390f35b6101e7565b5f80fd5b60401c90565b60ff1690565b610a19610a1e91610a01565b610a07565b90565b610a2b9054610a0d565b90565b5f1c90565b67ffffffffffffffff1690565b610a4c610a5191610a2e565b610a33565b90565b610a5e9054610a40565b90565b67ffffffffffffffff1690565b90565b610a85610a80610a8a92610a6e565b61037c565b610a61565b90565b90565b610aa4610a9f610aa992610a8d565b61037c565b610a61565b90565b610ab59061039b565b90565b610acc610ac7610ad192610a6e565b61037c565b61043f565b90565b5f1b90565b90610aec67ffffffffffffffff91610ad4565b9181191691161790565b610b0a610b05610b0f92610a61565b61037c565b610a61565b90565b90565b90610b2a610b25610b3192610af6565b610b12565b8254610ad9565b9055565b60401b90565b90610b4f68ff000000000000000091610b35565b9181191691161790565b610b6290610236565b90565b90565b90610b7d610b78610b8492610b59565b610b65565b8254610b3b565b9055565b610b9190610a90565b9052565b9190610ba8905f60208501940190610b88565b565b91939092610bb66111dd565b94610bcb610bc55f8801610a21565b15610236565b94610bd75f8801610a54565b80610bea610be45f610a71565b91610a61565b1480610d0b575b90610c05610bff6001610a90565b91610a61565b1480610ce3575b610c17909115610236565b9081610cd2575b50610caf57610c4794610c3c610c346001610a90565b5f8a01610b15565b86610c9d575b61109d565b610c4f575b50565b610c5c905f809101610b68565b6001610c947fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d291610c8b6101e1565b91829182610b95565b0390a15f610c4c565b610caa60015f8a01610b68565b610c42565b610cb76101e1565b63f92ee8a960e01b815280610cce600482016101fe565b0390fd5b610cdd915015610236565b5f610c1e565b50610c17610cf030610aac565b3b610d03610cfd5f610ab8565b9161043f565b149050610c0c565b5086610bf1565b610d26610d21610d2b92610a6e565b61037c565b610371565b90565b610d3790610d12565b90565b60209181520190565b5f7f496e76616c6964207072696d617279206f7261636c6500000000000000000000910152565b610d776016602092610d3a565b610d8081610d43565b0190565b610d999060208101905f818303910152610d6a565b90565b15610da357565b610dab6101e1565b62461bcd60e51b815280610dc160048201610d84565b0390fd5b5f7f496e76616c6964206261636b7570206f7261636c650000000000000000000000910152565b610df96015602092610d3a565b610e0281610dc5565b0190565b610e1b9060208101905f818303910152610dec565b90565b15610e2557565b610e2d6101e1565b62461bcd60e51b815280610e4360048201610e06565b0390fd5b5f7f4f7261636c6573206d75737420626520646966666572656e7400000000000000910152565b610e7b6019602092610d3a565b610e8481610e47565b0190565b610e9d9060208101905f818303910152610e6e565b90565b15610ea757565b610eaf6101e1565b62461bcd60e51b815280610ec560048201610e88565b0390fd5b60207f7469766500000000000000000000000000000000000000000000000000000000917f446576696174696f6e207468726573686f6c64206d75737420626520706f73695f8201520152565b610f236024604092610d3a565b610f2c81610ec9565b0190565b610f459060208101905f818303910152610f16565b90565b15610f4f57565b610f576101e1565b62461bcd60e51b815280610f6d60048201610f30565b0390fd5b90610f8260018060a01b0391610ad4565b9181191691161790565b610f959061037f565b90565b610fa190610f8c565b90565b90565b90610fbc610fb7610fc392610f98565b610fa4565b8254610f71565b9055565b90610fd35f1991610ad4565b9181191691161790565b610ff1610fec610ff69261043f565b61037c565b61043f565b90565b90565b9061101161100c61101892610fdd565b610ff9565b8254610fc7565b9055565b5f7f4d4f44543a20496e697469616c20646576696174696f6e20746f6f2068696768910152565b61104f60208092610d3a565b6110588161101c565b0190565b6110719060208101905f818303910152611043565b90565b1561107b57565b6110836101e1565b62461bcd60e51b8152806110996004820161105c565b0390fd5b926111a69461117761117e9261116561119f96956110de6110bd8a6103a7565b6110d76110d16110cc5f610d2e565b610776565b91610776565b1415610d9c565b61110b6110ea826103a7565b6111046110fe6110f95f610d2e565b610776565b91610776565b1415610e1e565b6111386111178a6103a7565b61113161112b611126856103a7565b610776565b91610776565b1415610ea0565b6111548761114e6111485f610ab8565b9161043f565b11610f48565b61115e895f610fa7565b6001610fa7565b611170856002610ffc565b6003610ffc565b6004610ffc565b61119861119261118c611763565b9261043f565b9161043f565b1115611074565b6005610fa7565b6111b96111b25f610ab8565b6006610ffc565b6111cc6111c55f610ab8565b6007610ffc565b565b906111db94939291610baa565b565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0090565b5f90565b61121161121691610a2e565b610331565b90565b6112239054611205565b90565b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b9061124e90611226565b810190811067ffffffffffffffff82111761126857604052565b611230565b60e01b90565b90505190611280826107b1565b565b9060208282031261129b57611298915f01611273565b90565b6101eb565b6112a86101e1565b3d5f823e3d90fd5b6112b8611201565b906112e660206112d06112cb6005611219565b6103a7565b63a035b1fe906112de6101e1565b93849261126d565b825281806112f6600482016101fe565b03915afa80915f92611435575b50155f1461142f5750600161131457565b905061131e611586565b5f146113aa57611351602061133b6113366001611219565b6103a7565b63a035b1fe906113496101e1565b93849261126d565b82528180611361600482016101fe565b03915afa9081156113a5575f91611377575b5090565b611398915060203d811161139e575b6113908183611244565b810190611282565b5f611373565b503d611386565b6112a0565b6113d660206113c06113bb5f611219565b6103a7565b63a035b1fe906113ce6101e1565b93849261126d565b825281806113e6600482016101fe565b03915afa90811561142a575f916113fc575b5090565b61141d915060203d8111611423575b6114158183611244565b810190611282565b5f6113f8565b503d61140b565b6112a0565b90915090565b61145791925060203d811161145e575b61144f8183611244565b810190611282565b905f611303565b503d611445565b61146d611201565b5061149a602061148461147f5f611219565b6103a7565b63a035b1fe906114926101e1565b93849261126d565b825281806114aa600482016101fe565b03915afa9081156114ee575f916114c0575b5090565b6114e1915060203d81116114e7575b6114d98183611244565b810190611282565b5f6114bc565b503d6114cf565b6112a0565b6114fb611201565b50611529602061151361150e6001611219565b6103a7565b63a035b1fe906115216101e1565b93849261126d565b82528180611539600482016101fe565b03915afa90811561157d575f9161154f575b5090565b611570915060203d8111611576575b6115688183611244565b810190611282565b5f61154b565b503d61155e565b6112a0565b5f90565b61158e611582565b506115996005611219565b6115b36115ad6115a85f611219565b610782565b91610782565b1490565b6115bf611582565b506115ca6005611219565b6115e56115df6115da6001611219565b610782565b91610782565b1490565b6115f56115fa91610a2e565b6104ce565b90565b61160790546115e9565b90565b611612611582565b5061161d60066115fd565b61162f6116295f610ab8565b9161043f565b1190565b61163b611582565b5061164660076115fd565b6116586116525f610ab8565b9161043f565b1190565b634e487b7160e01b5f52601160045260245ffd5b61167f6116859193929361043f565b9261043f565b820391821161169057565b61165c565b6116a46116aa9193929361043f565b9261043f565b82018092116116b557565b61165c565b90565b6116d16116cc6116d6926116ba565b61037c565b61043f565b90565b634e487b7160e01b5f52601260045260245ffd5b6116f96116ff9161043f565b9161043f565b90811561170a570490565b6116d9565b90565b61172661172161172b9261170f565b61037c565b61043f565b90565b61173d6117439193929361043f565b9261043f565b9161174f83820261043f565b92818404149015171561175e57565b61165c565b61176b611201565b50611798602061178261177d5f611219565b6103a7565b63a035b1fe906117906101e1565b93849261126d565b825281806117a8600482016101fe565b03915afa908115611937575f91611909575b506117e860206117d26117cd6001611219565b6103a7565b63a035b1fe906117e06101e1565b93849261126d565b825281806117f8600482016101fe565b03915afa908115611904575f916118d6575b50908061181f6118195f610ab8565b9161043f565b14806118bc575b6118ae5761189561187d61186d61189a9461183f611201565b508461185361184d8361043f565b9161043f565b10155f1461189d57611866858290611670565b945b611695565b61187760026116bd565b906116ed565b9161188f670de0b6b3a7640000611712565b9061172e565b6116ed565b90565b6118a8818690611670565b94611868565b50506118b95f610ab8565b90565b50816118d06118ca5f610ab8565b9161043f565b14611826565b6118f7915060203d81116118fd575b6118ef8183611244565b810190611282565b5f61180a565b503d6118e5565b6112a0565b61192a915060203d8111611930575b6119228183611244565b810190611282565b5f6117ba565b503d611918565b6112a0565b611944611582565b5061194d611763565b61196861196261195d60026115fd565b61043f565b9161043f565b1190565b5f7f4d4f44543a204d757374206265207072696d617279206f7261636c6500000000910152565b6119a0601c602092610d3a565b6119a98161196c565b0190565b6119c29060208101905f818303910152611993565b90565b156119cc57565b6119d46101e1565b62461bcd60e51b8152806119ea600482016119ad565b0390fd5b5f7f4d4f44543a20416c7265616479206368616c6c656e6765640000000000000000910152565b611a226018602092610d3a565b611a2b816119ee565b0190565b611a449060208101905f818303910152611a15565b90565b15611a4e57565b611a566101e1565b62461bcd60e51b815280611a6c60048201611a2f565b0390fd5b60207f7400000000000000000000000000000000000000000000000000000000000000917f4d4f44543a20446576696174696f6e207468726573686f6c64206e6f74206d655f8201520152565b611aca6021604092610d3a565b611ad381611a70565b0190565b611aec9060208101905f818303910152611abd565b90565b15611af657565b611afe6101e1565b62461bcd60e51b815280611b1460048201611ad7565b0390fd5b611b28611b23611586565b6119c5565b611b41611b3c611b3661160a565b15610236565b611a47565b611b51611b4c61193c565b611aef565b611b6f611b6842611b6260036115fd565b90611695565b6006610ffc565b611b7960066115fd565b611baf7fa895da4b794aeba8d8082db237265459db7b7ffdb5aa7c2332a7c5eafbfae73591611ba66101e1565b9182918261044f565b0390a1565b5f7f4d4f44543a204e6f74206368616c6c656e676564000000000000000000000000910152565b611be86014602092610d3a565b611bf181611bb4565b0190565b611c0a9060208101905f818303910152611bdb565b90565b15611c1457565b611c1c6101e1565b62461bcd60e51b815280611c3260048201611bf5565b0390fd5b60207f6d65740000000000000000000000000000000000000000000000000000000000917f4d4f44543a20446576696174696f6e207468726573686f6c64207374696c6c205f8201520152565b611c906023604092610d3a565b611c9981611c36565b0190565b611cb29060208101905f818303910152611c83565b90565b15611cbc57565b611cc46101e1565b62461bcd60e51b815280611cda60048201611c9d565b0390fd5b611cee611ce9611586565b6119c5565b611cfe611cf961160a565b611c0d565b611d17611d12611d0c61193c565b15610236565b611cb5565b611d2a611d235f610ab8565b6006610ffc565b7f50b374cefefbe966ce88eecb3ec50723325b080e27f17d311661c9c079095788611d536101e1565b80611d5d816101fe565b0390a1565b611d6a611582565b50611d7361160a565b80611d7c575b90565b5042611d99611d93611d8e60066115fd565b61043f565b9161043f565b1015611d79565b611da8611582565b50611db1611586565b80611df8575b80611dd4575b80611dc6575b90565b50611dcf61193c565b611dc3565b5042611df1611deb611de660066115fd565b61043f565b9161043f565b1015611dbd565b50611e0161160a565b611db7565b60207f7365640000000000000000000000000000000000000000000000000000000000917f4d4f44543a204368616c6c656e67652074696d656c6f636b206e6f74207061735f8201520152565b611e606023604092610d3a565b611e6981611e06565b0190565b611e829060208101905f818303910152611e53565b90565b15611e8c57565b611e946101e1565b62461bcd60e51b815280611eaa60048201611e6d565b0390fd5b5f7f4d4f44543a20446576696174696f6e207265736f6c7665640000000000000000910152565b611ee26018602092610d3a565b611eeb81611eae565b0190565b611f049060208101905f818303910152611ed5565b90565b15611f0e57565b611f166101e1565b62461bcd60e51b815280611f2c60048201611eef565b0390fd5b611f399061039b565b90565b611f4c611f47611586565b6119c5565b611f5c611f5761160a565b611c0d565b611f8242611f7b611f75611f7060066115fd565b61043f565b9161043f565b1015611e85565b611f92611f8d61193c565b611f07565b611fa6611f9f6001611219565b6005610fa7565b611fb9611fb25f610ab8565b6006610ffc565b611fcb611fc66005611219565b6103a7565b611ff57f235d3c92abef402ad8969f43056a1212760efee2e4357b1e165a93aed19329e391611f30565b90611ffe6101e1565b80612008816101fe565b0390a2565b5f7f4d4f44543a204d757374206265206261636b7570206f7261636c650000000000910152565b612041601b602092610d3a565b61204a8161200d565b0190565b6120639060208101905f818303910152612034565b90565b1561206d57565b6120756101e1565b62461bcd60e51b81528061208b6004820161204e565b0390fd5b5f7f4d4f44543a20416c7265616479206865616c696e670000000000000000000000910152565b6120c36015602092610d3a565b6120cc8161208f565b0190565b6120e59060208101905f8183039101526120b6565b90565b156120ef57565b6120f76101e1565b62461bcd60e51b81528061210d600482016120d0565b0390fd5b61212161211c6115b7565b612066565b61213a61213561212f611633565b15610236565b6120e8565b61215361214e61214861193c565b15610236565b611cb5565b61217161216a4261216460046115fd565b90611695565b6007610ffc565b61217b60076115fd565b6121b17fb36d2484c6d35cccf36d46eafe82aa81628f80b9c4e6d1828f5837236a0641bd916121a86101e1565b9182918261044f565b0390a1565b5f7f4d4f44543a204e6f74206865616c696e67000000000000000000000000000000910152565b6121ea6011602092610d3a565b6121f3816121b6565b0190565b61220c9060208101905f8183039101526121dd565b90565b1561221657565b61221e6101e1565b62461bcd60e51b815280612234600482016121f7565b0390fd5b6122486122436115b7565b612066565b612258612253611633565b61220f565b61226861226361193c565b611aef565b61227b6122745f610ab8565b6007610ffc565b7ff5decdb337f3f69eb4a1610788fd6d8325897945c0f070fef7218c25b84ea9086122a46101e1565b806122ae816101fe565b0390a1565b6122bb611582565b506122c4611633565b806122cd575b90565b50426122ea6122e46122df60076115fd565b61043f565b9161043f565b10156122ca565b6122f9611582565b506123026115b7565b80612352575b8061232e575b80612317575b90565b5061232961232361193c565b15610236565b612314565b504261234b61234561234060076115fd565b61043f565b9161043f565b101561230e565b5061235b611633565b612308565b60207f6400000000000000000000000000000000000000000000000000000000000000917f4d4f44543a204865616c696e672074696d656c6f636b206e6f742070617373655f8201520152565b6123ba6021604092610d3a565b6123c381612360565b0190565b6123dc9060208101905f8183039101526123ad565b90565b156123e657565b6123ee6101e1565b62461bcd60e51b815280612404600482016123c7565b0390fd5b5f7f4d4f44543a20446576696174696f6e206f636375727265640000000000000000910152565b61243c6018602092610d3a565b61244581612408565b0190565b61245e9060208101905f81830391015261242f565b90565b1561246857565b6124706101e1565b62461bcd60e51b81528061248660048201612449565b0390fd5b61249a6124956115b7565b612066565b6124aa6124a5611633565b61220f565b6124d0426124c96124c36124be60076115fd565b61043f565b9161043f565b10156123df565b6124e96124e46124de61193c565b15610236565b612461565b6124fc6124f55f611219565b6005610fa7565b61250f6125085f610ab8565b6007610ffc565b61252161251c6005611219565b6103a7565b61254b7f184591035d84fab784c414962589ca8bf109c62ce76e7b318ca83c16c7c63b6491611f30565b906125546101e1565b8061255e816101fe565b0390a256fea264697066735822122015cfd0175abc18a76f1dff65ef160b3f2a606ee3109d70184621344cacf0a25064736f6c63430008150033
Deployed Bytecode
0x60806040526004361015610013575b61022e565b61001d5f3561003c565b80635c60da1b146100375763f3afc37b0361000e576101f5565b6100bc565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f91031261005a57565b61004c565b7f0000000000000000000000007ad38ea164e9396c76ccde96187ba0dac4fbaaa690565b60018060a01b031690565b61009790610083565b90565b6100a39061008e565b9052565b91906100ba905f6020850194019061009a565b565b346100ec576100cc366004610050565b6100e86100d761005f565b6100df610042565b918291826100a7565b0390f35b610048565b6100fa9061008e565b90565b610106816100f1565b0361010d57565b5f80fd5b9050359061011e826100fd565b565b90565b61012c81610120565b0361013357565b5f80fd5b9050359061014482610123565b565b919060a0838203126101975761015e815f8501610111565b9261016c8260208301610111565b9261019461017d8460408501610137565b9361018b8160608601610137565b93608001610137565b90565b61004c565b90565b6101b36101ae6101b892610083565b61019c565b610083565b90565b6101c49061019f565b90565b6101d0906101bb565b90565b6101dc906101c7565b9052565b91906101f3905f602085019401906101d3565b565b346102295761022561021461020b366004610146565b9392909261039f565b61021c610042565b918291826101e0565b0390f35b610048565b5f80fd5b5f90565b61023f9061019f565b90565b61024b90610236565b90565b6102579061019f565b90565b6102639061024e565b90565b61026f906101bb565b90565b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b9061029e90610276565b810190811067ffffffffffffffff8211176102b857604052565b610280565b60e01b90565b5f9103126102cd57565b61004c565b6102db906101bb565b90565b6102e7906102d2565b9052565b6102f490610120565b9052565b909594926103439461033261033c9261032860809661031e60a088019c5f8901906102de565b60208701906102de565b60408501906102eb565b60608301906102eb565b01906102eb565b565b61034d610042565b3d5f823e3d90fd5b61035e906101bb565b90565b61039661039d9461038c606094989795610382608086019a5f87019061009a565b60208501906102eb565b60408301906102eb565b01906102eb565b565b949392946103ab610232565b506103d57f0000000000000000000000007ad38ea164e9396c76ccde96187ba0dac4fbaaa661053f565b956103f06103eb6103e589610242565b9861025a565b610266565b63d13f90b48385928792858a91833b156105065761042f610424935f97938894610418610042565b9a8b998a9889976102bd565b8752600487016102f8565b03925af18015610501576104d5575b50610448876101c7565b916104d061047f6104797f0000000000000000000000007ad38ea164e9396c76ccde96187ba0dac4fbaaa6936102d2565b956102d2565b9592966104be6104b86104b27fff56edf5f37154a80711a8b72abc534ce41632b43d407c139574fe8850c65ce997610355565b97610355565b97610355565b976104c7610042565b94859485610361565b0390a4565b6104f4905f3d81116104fa575b6104ec8183610294565b8101906102c3565b5f61043e565b503d6104e2565b610345565b610272565b5f90565b90565b61052661052161052b9261050f565b61019c565b610083565b90565b61053790610512565b90565b5f0190565b6e5af43d82803e903d91602b57fd5bf39061055861050b565b50763d602d80600a3d3981f3363d3d373d3d3d363d730000008160601b60e81c175f5260781b17602052603760095ff090816105a461059e6105995f61052e565b61008e565b9161008e565b146105ab57565b6105b3610042565b6330be1a3d60e21b8152806105ca6004820161053a565b0390fdfea2646970667358221220722f68207d7be3ca02688b263ded68b06557b5fd350d2e5bc462945df20dd06964736f6c63430008150033
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.