Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 19069551 | 217 days ago | IN | 0 ETH | 0.00750357 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
FrxETHPriceOracle
Compiler Version
v0.8.17+commit.8df45f5f
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "Denominations.sol"; import "IOracle.sol"; import {IAggregatorV3Interface} from "ChainlinkOracle.sol"; contract FrxETHPriceOracle is IOracle { address public constant ETH_USD_FEED = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419; uint256 public constant ETH_USD_FEED_MULTIPLIER = 10 ** 8; // ETH/USD feed has 8 decimals address public constant FRAX_ETH = 0x5E8422345238F34275888049021821E8E08CAa1f; address public constant FRAX_ETH_ETH_FEED = 0xC58F3385FBc1C8AD2c0C9a061D7c13b141D7A5Df; uint256 public constant HEARTBEAT = 90_000; // FRAX_ETH_ETH_FEED.maximumOracleDelay = 25 hours function getUSDPrice(address token) external view override returns (uint256) { require(token == FRAX_ETH, "only supports FRXETH"); uint256 ethPrice_ = _getPrice(ETH_USD_FEED); uint256 frxEthEthPrice_ = _getPrice(FRAX_ETH_ETH_FEED); return (ethPrice_ * frxEthEthPrice_) / ETH_USD_FEED_MULTIPLIER; } function _getPrice(address feed) internal view returns (uint256) { IAggregatorV3Interface feed_ = IAggregatorV3Interface(feed); (, int256 price_, , uint256 updatedAt_, ) = feed_.latestRoundData(); require(price_ > 0, "negative price"); require(updatedAt_ >= block.timestamp - HEARTBEAT, "price too old"); return uint256(price_); } function isTokenSupported(address token) external pure override returns (bool) { return token == FRAX_ETH; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library Denominations { address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; address public constant BTC = 0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB; // Fiat currencies follow https://en.wikipedia.org/wiki/ISO_4217 address public constant USD = address(840); address public constant GBP = address(826); address public constant EUR = address(978); address public constant JPY = address(392); address public constant KRW = address(410); address public constant CNY = address(156); address public constant AUD = address(36); address public constant CAD = address(124); address public constant CHF = address(756); address public constant ARS = address(32); address public constant PHP = address(608); address public constant NZD = address(554); address public constant SGD = address(702); address public constant NGN = address(566); address public constant ZAR = address(710); address public constant RUB = address(643); address public constant INR = address(356); address public constant BRL = address(986); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; interface IOracle { event TokenUpdated(address indexed token, address feed, uint256 maxDelay, bool isEthPrice); /// @notice returns the price in USD of symbol. function getUSDPrice(address token) external view returns (uint256); /// @notice returns if the given token is supported for pricing. function isTokenSupported(address token) external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.8.17; import "Denominations.sol"; import "FeedRegistryInterface.sol"; import "Ownable.sol"; import "IOracle.sol"; interface IAggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); /// @notice `getRoundData` and `latestRoundData` should both raise "No data present" /// if they do not have data to report, instead of returning unset values /// which could be misinterpreted as actual reported values. 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 ); } contract ChainlinkOracle is IOracle, Ownable { event HeartbeatUpdated(uint256 heartbeat); uint256 public heartbeat = 24 hours; FeedRegistryInterface internal constant _feedRegistry = FeedRegistryInterface(0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf); address internal constant _WETH = address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); address internal constant _CURVE_ETH = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); uint256 internal constant _MIN_HEARTBEAT = 6 hours; function setHeartbeat(uint256 heartbeat_) external onlyOwner { require(heartbeat_ >= _MIN_HEARTBEAT, "heartbeat too low"); require(heartbeat_ != heartbeat, "same as current"); heartbeat = heartbeat_; emit HeartbeatUpdated(heartbeat_); } function isTokenSupported(address token) external view override returns (bool) { if (_isEth(token)) return true; try this.getUSDPrice(token) returns (uint256) { return true; } catch Error(string memory) { return false; } } // Prices are always provided with 18 decimals pecision function getUSDPrice(address token) external view returns (uint256) { return _getPrice(token, Denominations.USD, true); } function _getPrice( address token, address denomination, bool tryOtherDenomination ) internal view returns (uint256) { if (_isEth(token)) token = Denominations.ETH; try _feedRegistry.latestRoundData(token, denomination) returns ( uint80, int256 price_, uint256, uint256 updatedAt_, uint80 ) { require(updatedAt_ != 0, "round not complete"); require(price_ > 0, "negative price"); require(updatedAt_ >= block.timestamp - heartbeat, "price too old"); return _scaleFrom(uint256(price_), _feedRegistry.decimals(token, denomination)); } catch Error(string memory reason) { if (!tryOtherDenomination) revert(reason); if (denomination == Denominations.USD) { return (_getPrice(token, Denominations.ETH, false) * _getPrice(Denominations.ETH, Denominations.USD, false)) / 1e18; } return (_getPrice(token, Denominations.USD, false) * 1e18) / _getPrice(Denominations.ETH, Denominations.USD, false); } } function _scaleFrom(uint256 value, uint8 decimals) internal pure returns (uint256) { if (decimals == 18) return value; if (decimals > 18) return value / 10 ** (decimals - 18); else return value * 10 ** (18 - decimals); } function _isEth(address token) internal pure returns (bool) { return token == address(0) || token == _WETH || token == _CURVE_ETH; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma abicoder v2; import "AggregatorV2V3Interface.sol"; interface FeedRegistryInterface { struct Phase { uint16 phaseId; uint80 startingAggregatorRoundId; uint80 endingAggregatorRoundId; } event FeedProposed( address indexed asset, address indexed denomination, address indexed proposedAggregator, address currentAggregator, address sender ); event FeedConfirmed( address indexed asset, address indexed denomination, address indexed latestAggregator, address previousAggregator, uint16 nextPhaseId, address sender ); // V3 AggregatorV3Interface function decimals(address base, address quote) external view returns (uint8); function description(address base, address quote) external view returns (string memory); function version(address base, address quote) external view returns (uint256); function latestRoundData(address base, address quote) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function getRoundData( address base, address quote, uint80 _roundId ) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); // V2 AggregatorInterface function latestAnswer(address base, address quote) external view returns (int256 answer); function latestTimestamp(address base, address quote) external view returns (uint256 timestamp); function latestRound(address base, address quote) external view returns (uint256 roundId); function getAnswer( address base, address quote, uint256 roundId ) external view returns (int256 answer); function getTimestamp( address base, address quote, uint256 roundId ) external view returns (uint256 timestamp); // Registry getters function getFeed(address base, address quote) external view returns (AggregatorV2V3Interface aggregator); function getPhaseFeed( address base, address quote, uint16 phaseId ) external view returns (AggregatorV2V3Interface aggregator); function isFeedEnabled(address aggregator) external view returns (bool); function getPhase( address base, address quote, uint16 phaseId ) external view returns (Phase memory phase); // Round helpers function getRoundFeed( address base, address quote, uint80 roundId ) external view returns (AggregatorV2V3Interface aggregator); function getPhaseRange( address base, address quote, uint16 phaseId ) external view returns (uint80 startingRoundId, uint80 endingRoundId); function getPreviousRoundId( address base, address quote, uint80 roundId ) external view returns (uint80 previousRoundId); function getNextRoundId( address base, address quote, uint80 roundId ) external view returns (uint80 nextRoundId); // Feed management function proposeFeed( address base, address quote, address aggregator ) external; function confirmFeed( address base, address quote, address aggregator ) external; // Proposed aggregator function getProposedFeed(address base, address quote) external view returns (AggregatorV2V3Interface proposedAggregator); function proposedGetRoundData( address base, address quote, uint80 roundId ) external view returns ( uint80 id, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function proposedLatestRoundData(address base, address quote) external view returns ( uint80 id, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); // Phases function getCurrentPhaseId(address base, address quote) external view returns (uint16 currentPhaseId); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "AggregatorInterface.sol"; import "AggregatorV3Interface.sol"; interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface {}
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorInterface { function latestAnswer() external view returns (int256); function latestTimestamp() external view returns (uint256); function latestRound() external view returns (uint256); function getAnswer(uint256 roundId) external view returns (int256); function getTimestamp(uint256 roundId) external view returns (uint256); event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt); event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; 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 ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
{ "evmVersion": "london", "optimizer": { "enabled": true, "runs": 200 }, "libraries": { "FrxETHOracle.sol": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"feed","type":"address"},{"indexed":false,"internalType":"uint256","name":"maxDelay","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isEthPrice","type":"bool"}],"name":"TokenUpdated","type":"event"},{"inputs":[],"name":"ETH_USD_FEED","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_FEED_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FRAX_ETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FRAX_ETH_ETH_FEED","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HEARTBEAT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getUSDPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"isTokenSupported","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50610477806100206000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c806375151b631161005b57806375151b63146100ed5780638b2f0f4f1461012d57806394d8572a14610140578063f18fb8e81461015b57600080fd5b806304e4fdf4146100825780631586b388146100ba578063297887b5146100d2575b600080fd5b61009d735e8422345238f34275888049021821e8e08caa1f81565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c462015f9081565b6040519081526020016100b1565b61009d73c58f3385fbc1c8ad2c0c9a061d7c13b141d7a5df81565b61011d6100fb36600461033a565b6001600160a01b0316735e8422345238f34275888049021821e8e08caa1f1490565b60405190151581526020016100b1565b6100c461013b36600461033a565b610166565b61009d735f4ec3df9cbd43714fe2740f5e3616155c5b841981565b6100c46305f5e10081565b60006001600160a01b038216735e8422345238f34275888049021821e8e08caa1f146101d05760405162461bcd60e51b81526020600482015260146024820152730dedcd8f240e6eae0e0dee4e8e6408ca4b08aa8960631b60448201526064015b60405180910390fd5b60006101ef735f4ec3df9cbd43714fe2740f5e3616155c5b8419610233565b9050600061021073c58f3385fbc1c8ad2c0c9a061d7c13b141d7a5df610233565b90506305f5e1006102218284610380565b61022b919061039d565b949350505050565b600080829050600080826001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561027a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029e91906103de565b50935050925050600082136102e65760405162461bcd60e51b815260206004820152600e60248201526d6e6567617469766520707269636560901b60448201526064016101c7565b6102f362015f904261042e565b8110156103325760405162461bcd60e51b815260206004820152600d60248201526c1c1c9a58d9481d1bdbc81bdb19609a1b60448201526064016101c7565b509392505050565b60006020828403121561034c57600080fd5b81356001600160a01b038116811461036357600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176103975761039761036a565b92915050565b6000826103ba57634e487b7160e01b600052601260045260246000fd5b500490565b805169ffffffffffffffffffff811681146103d957600080fd5b919050565b600080600080600060a086880312156103f657600080fd5b6103ff866103bf565b9450602086015193506040860151925060608601519150610422608087016103bf565b90509295509295909350565b818103818111156103975761039761036a56fea26469706673582212203bbfc9e5a4574d9ebf0e3b3bb9292631b563ec21e625626ec94650046dcbb17164736f6c63430008110033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061007d5760003560e01c806375151b631161005b57806375151b63146100ed5780638b2f0f4f1461012d57806394d8572a14610140578063f18fb8e81461015b57600080fd5b806304e4fdf4146100825780631586b388146100ba578063297887b5146100d2575b600080fd5b61009d735e8422345238f34275888049021821e8e08caa1f81565b6040516001600160a01b0390911681526020015b60405180910390f35b6100c462015f9081565b6040519081526020016100b1565b61009d73c58f3385fbc1c8ad2c0c9a061d7c13b141d7a5df81565b61011d6100fb36600461033a565b6001600160a01b0316735e8422345238f34275888049021821e8e08caa1f1490565b60405190151581526020016100b1565b6100c461013b36600461033a565b610166565b61009d735f4ec3df9cbd43714fe2740f5e3616155c5b841981565b6100c46305f5e10081565b60006001600160a01b038216735e8422345238f34275888049021821e8e08caa1f146101d05760405162461bcd60e51b81526020600482015260146024820152730dedcd8f240e6eae0e0dee4e8e6408ca4b08aa8960631b60448201526064015b60405180910390fd5b60006101ef735f4ec3df9cbd43714fe2740f5e3616155c5b8419610233565b9050600061021073c58f3385fbc1c8ad2c0c9a061d7c13b141d7a5df610233565b90506305f5e1006102218284610380565b61022b919061039d565b949350505050565b600080829050600080826001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa15801561027a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061029e91906103de565b50935050925050600082136102e65760405162461bcd60e51b815260206004820152600e60248201526d6e6567617469766520707269636560901b60448201526064016101c7565b6102f362015f904261042e565b8110156103325760405162461bcd60e51b815260206004820152600d60248201526c1c1c9a58d9481d1bdbc81bdb19609a1b60448201526064016101c7565b509392505050565b60006020828403121561034c57600080fd5b81356001600160a01b038116811461036357600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176103975761039761036a565b92915050565b6000826103ba57634e487b7160e01b600052601260045260246000fd5b500490565b805169ffffffffffffffffffff811681146103d957600080fd5b919050565b600080600080600060a086880312156103f657600080fd5b6103ff866103bf565b9450602086015193506040860151925060608601519150610422608087016103bf565b90509295509295909350565b818103818111156103975761039761036a56fea26469706673582212203bbfc9e5a4574d9ebf0e3b3bb9292631b563ec21e625626ec94650046dcbb17164736f6c63430008110033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.