Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 9 from a total of 9 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Add | 13802865 | 998 days ago | IN | 0 ETH | 0.00239784 | ||||
Add | 13802859 | 998 days ago | IN | 0 ETH | 0.00199804 | ||||
Add | 13802849 | 998 days ago | IN | 0 ETH | 0.00186314 | ||||
Add | 13745668 | 1007 days ago | IN | 0 ETH | 0.00304187 | ||||
Add | 13745637 | 1007 days ago | IN | 0 ETH | 0.00232381 | ||||
Add | 13745632 | 1007 days ago | IN | 0 ETH | 0.00254737 | ||||
Add | 13745619 | 1007 days ago | IN | 0 ETH | 0.00378338 | ||||
Add | 13390359 | 1063 days ago | IN | 0 ETH | 0.00236145 | ||||
Add | 13390250 | 1063 days ago | IN | 0 ETH | 0.0023125 |
Latest 1 internal transaction
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
13390007 | 1063 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Minimal Proxy Contract for 0xb3c8ee7309be658c186f986388c2377da436d8fb
Contract Name:
MasterPriceOracle
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.6.12; import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; import "../external/compound/PriceOracle.sol"; import "../external/compound/CToken.sol"; import "../external/compound/CErc20.sol"; import "./BasePriceOracle.sol"; /** * @title MasterPriceOracle * @notice Use a combination of price oracles. * @dev Implements `PriceOracle`. * @author David Lucid <[email protected]> (https://github.com/davidlucid) */ contract MasterPriceOracle is Initializable, PriceOracle, BasePriceOracle { /** * @dev Maps underlying token addresses to `PriceOracle` contracts (can be `BasePriceOracle` contracts too). */ mapping(address => PriceOracle) public oracles; /** * @dev Default/fallback `PriceOracle`. */ PriceOracle public defaultOracle; /** * @dev The administrator of this `MasterPriceOracle`. */ address public admin; /** * @dev Controls if `admin` can overwrite existing assignments of oracles to underlying tokens. */ bool internal noAdminOverwrite; /** * @dev Returns a boolean indicating if `admin` can overwrite existing assignments of oracles to underlying tokens. */ function canAdminOverwrite() external view returns (bool) { return !noAdminOverwrite; } /** * @dev Event emitted when `admin` is changed. */ event NewAdmin(address oldAdmin, address newAdmin); /** * @dev Event emitted when the default oracle is changed. */ event NewDefaultOracle(address oldOracle, address newOracle); /** * @dev Event emitted when an underlying token's oracle is changed. */ event NewOracle(address underlying, address oldOracle, address newOracle); /** * @dev Constructor to initialize state variables. * @param underlyings The underlying ERC20 token addresses to link to `_oracles`. * @param _oracles The `PriceOracle` contracts to be assigned to `underlyings`. * @param _defaultOracle The default `PriceOracle` contract to use. * @param _admin The admin who can assign oracles to underlying tokens. * @param _canAdminOverwrite Controls if `admin` can overwrite existing assignments of oracles to underlying tokens. */ function initialize(address[] memory underlyings, PriceOracle[] memory _oracles, PriceOracle _defaultOracle, address _admin, bool _canAdminOverwrite) external initializer { // Input validation require(underlyings.length == _oracles.length, "Lengths of both arrays must be equal."); // Initialize state variables for (uint256 i = 0; i < underlyings.length; i++) { address underlying = underlyings[i]; PriceOracle newOracle = _oracles[i]; oracles[underlying] = newOracle; emit NewOracle(underlying, address(0), address(newOracle)); } defaultOracle = _defaultOracle; admin = _admin; noAdminOverwrite = !_canAdminOverwrite; } /** * @dev Sets `_oracles` for `underlyings`. */ function add(address[] calldata underlyings, PriceOracle[] calldata _oracles) external onlyAdmin { // Input validation require(underlyings.length > 0 && underlyings.length == _oracles.length, "Lengths of both arrays must be equal and greater than 0."); // Assign oracles to underlying tokens for (uint256 i = 0; i < underlyings.length; i++) { address underlying = underlyings[i]; address oldOracle = address(oracles[underlying]); if (noAdminOverwrite) require(oldOracle == address(0), "Admin cannot overwrite existing assignments of oracles to underlying tokens."); PriceOracle newOracle = _oracles[i]; oracles[underlying] = newOracle; emit NewOracle(underlying, oldOracle, address(newOracle)); } } /** * @dev Changes the admin and emits an event. */ function setDefaultOracle(PriceOracle newOracle) external onlyAdmin { PriceOracle oldOracle = defaultOracle; defaultOracle = newOracle; emit NewDefaultOracle(address(oldOracle), address(newOracle)); } /** * @dev Changes the admin and emits an event. */ function changeAdmin(address newAdmin) external onlyAdmin { address oldAdmin = admin; admin = newAdmin; emit NewAdmin(oldAdmin, newAdmin); } /** * @dev Modifier that checks if `msg.sender == admin`. */ modifier onlyAdmin { require(msg.sender == admin, "Sender is not the admin."); _; } /** * @notice Returns the price in ETH of the token underlying `cToken`. * @dev Implements the `PriceOracle` interface for Fuse pools (and Compound v2). * @return Price in ETH of the token underlying `cToken`, scaled by `10 ** (36 - underlyingDecimals)`. */ function getUnderlyingPrice(CToken cToken) external override view returns (uint) { // Get underlying ERC20 token address address underlying = address(CErc20(address(cToken)).underlying()); // Return 1e18 for WETH if (underlying == 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) return 1e18; // Get underlying price from assigned oracle PriceOracle oracle = oracles[underlying]; if (address(oracle) != address(0)) return oracle.getUnderlyingPrice(cToken); if (address(defaultOracle) != address(0)) return defaultOracle.getUnderlyingPrice(cToken); revert("Price oracle not found for this underlying token address."); } /** * @dev Attempts to return the price in ETH of `underlying` (implements `BasePriceOracle`). */ function price(address underlying) external override view returns (uint) { // Return 1e18 for WETH if (underlying == 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2) return 1e18; // Get underlying price from assigned oracle PriceOracle oracle = oracles[underlying]; if (address(oracle) != address(0)) return BasePriceOracle(address(oracle)).price(underlying); if (address(defaultOracle) != address(0)) return BasePriceOracle(address(defaultOracle)).price(underlying); revert("Price oracle not found for this underlying token address."); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // solhint-disable-next-line compiler-version pragma solidity >=0.4.24 <0.8.0; import "../utils/AddressUpgradeable.sol"; /** * @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 a proxied contract can't have 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. * * 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 {UpgradeableProxy-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. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /// @dev Returns true if and only if the function is running in the constructor function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.6.12; import "../external/compound/PriceOracle.sol"; /** * @title BasePriceOracle * @notice Returns prices of underlying tokens directly without the caller having to specify a cToken address. * @dev Implements the `PriceOracle` interface. * @author David Lucid <[email protected]> (https://github.com/davidlucid) */ interface BasePriceOracle is PriceOracle { /** * @notice Get the price of an underlying asset. * @param underlying The underlying asset to get the price of. * @return The underlying asset price in ETH as a mantissa (scaled by 1e18). * Zero means the price is unavailable. */ function price(address underlying) external view returns (uint); }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.6.12; import "./CToken.sol"; interface PriceOracle { /** * @notice Get the underlying price of a cToken asset * @param cToken The cToken to get the underlying price of * @return The underlying asset price mantissa (scaled by 1e18). * Zero means the price is unavailable. */ function getUnderlyingPrice(CToken cToken) external view returns (uint); }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.6.12; /** * @title Compound's CToken Contract * @notice Abstract base for CTokens * @author Compound */ interface CToken { function admin() external view returns (address); function adminHasRights() external view returns (bool); function fuseAdminHasRights() external view returns (bool); function symbol() external view returns (string memory); function comptroller() external view returns (address); function adminFeeMantissa() external view returns (uint256); function fuseFeeMantissa() external view returns (uint256); function reserveFactorMantissa() external view returns (uint256); function totalReserves() external view returns (uint); function totalAdminFees() external view returns (uint); function totalFuseFees() external view returns (uint); function isCToken() external view returns (bool); function isCEther() external view returns (bool); function balanceOf(address owner) external view returns (uint); function balanceOfUnderlying(address owner) external returns (uint); function borrowRatePerBlock() external view returns (uint); function supplyRatePerBlock() external view returns (uint); function totalBorrowsCurrent() external returns (uint); function borrowBalanceStored(address account) external view returns (uint); function exchangeRateStored() external view returns (uint); function getCash() external view returns (uint); function redeem(uint redeemTokens) external returns (uint); function redeemUnderlying(uint redeemAmount) external returns (uint); }
// SPDX-License-Identifier: BSD-3-Clause pragma solidity 0.6.12; import "./CToken.sol"; /** * @title Compound's CErc20 Contract * @notice CTokens which wrap an EIP-20 underlying * @author Compound */ interface CErc20 is CToken { function underlying() external view returns (address); function liquidateBorrow(address borrower, uint repayAmount, CToken cTokenCollateral) external returns (uint); }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "istanbul", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"NewAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOracle","type":"address"},{"indexed":false,"internalType":"address","name":"newOracle","type":"address"}],"name":"NewDefaultOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"underlying","type":"address"},{"indexed":false,"internalType":"address","name":"oldOracle","type":"address"},{"indexed":false,"internalType":"address","name":"newOracle","type":"address"}],"name":"NewOracle","type":"event"},{"inputs":[{"internalType":"address[]","name":"underlyings","type":"address[]"},{"internalType":"contract PriceOracle[]","name":"_oracles","type":"address[]"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"admin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"canAdminOverwrite","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"changeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultOracle","outputs":[{"internalType":"contract PriceOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract CToken","name":"cToken","type":"address"}],"name":"getUnderlyingPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"underlyings","type":"address[]"},{"internalType":"contract PriceOracle[]","name":"_oracles","type":"address[]"},{"internalType":"contract PriceOracle","name":"_defaultOracle","type":"address"},{"internalType":"address","name":"_admin","type":"address"},{"internalType":"bool","name":"_canAdminOverwrite","type":"bool"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"oracles","outputs":[{"internalType":"contract PriceOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"underlying","type":"address"}],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract PriceOracle","name":"newOracle","type":"address"}],"name":"setDefaultOracle","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.