Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
EzEthOracle
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// =========================== EzEthOracle ============================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// ====================================================================
import { Timelock2Step } from "frax-std/access-control/v1/Timelock2Step.sol";
import { ITimelock2Step } from "frax-std/access-control/v1/interfaces/ITimelock2Step.sol";
import { DualOracleBase, ConstructorParams as DualOracleBaseParams } from "../DualOracleBase.sol";
import { IDualOracle } from "interfaces/IDualOracle.sol";
import { ERC165Storage } from "src/contracts/utils/ERC165Storage.sol";
import { EthUsdChainlinkOracleWithMaxDelay, ConstructorParams as EthUsdChainlinkOracleWithMaxDelayParams } from "../abstracts/EthUsdChainlinkOracleWithMaxDelay.sol";
import { Api3OracleWithMaxDelay, ConstructorParams as Api3OracleParams } from "src/contracts/abstracts/Api3OracleWithMaxDelay.sol";
struct ConstructorParams {
address ezEthErc20;
address timelockAddress;
address ethUsdFeedAddress;
uint256 ethUsdMaxOracleDelay;
address api3PriceFeed;
uint8 api3FeedDecimals;
uint256 maximumOracleDelayApi3;
}
contract EzEthOracle is DualOracleBase, Timelock2Step, Api3OracleWithMaxDelay, EthUsdChainlinkOracleWithMaxDelay {
address public immutable EZETH_ERC20;
constructor(
ConstructorParams memory _params
)
DualOracleBase(
DualOracleBaseParams({
baseToken0: address(840),
baseToken0Decimals: 18,
quoteToken0: _params.ezEthErc20,
quoteToken0Decimals: 18,
baseToken1: address(840),
baseToken1Decimals: 18,
quoteToken1: _params.ezEthErc20,
quoteToken1Decimals: 18
})
)
Timelock2Step()
EthUsdChainlinkOracleWithMaxDelay(
EthUsdChainlinkOracleWithMaxDelayParams({
ethUsdChainlinkFeedAddress: _params.ethUsdFeedAddress,
maxEthUsdOracleDelay: _params.ethUsdMaxOracleDelay
})
)
Api3OracleWithMaxDelay(
Api3OracleParams({
api3FeedAddress: _params.api3PriceFeed,
api3FeedDecimals: _params.api3FeedDecimals,
maximumOracleDelay: _params.maximumOracleDelayApi3
})
)
{
_setTimelock({ _newTimelock: _params.timelockAddress });
_registerInterface({ interfaceId: type(IDualOracle).interfaceId });
_registerInterface({ interfaceId: type(ITimelock2Step).interfaceId });
EZETH_ERC20 = _params.ezEthErc20;
}
// ====================================================================
// View Helpers
// ====================================================================
function name() external pure returns (string memory) {
return "EzEth Api3 + Redstone Oracle";
}
// ====================================================================
// Configuration Setters
// ====================================================================
/// @notice The ```setMaximumEthUsdOracleDelay``` function set the max oracle delay for the Eth/USD Redstone oracle
/// @dev Requires msg.sender to be the timelock address
/// @param _newMaxOracleDelay The new max oracle delay
function setMaximumEthUsdOracleDelay(uint256 _newMaxOracleDelay) external override {
_requireTimelock();
_setMaximumEthUsdOracleDelay({ _newMaxOracleDelay: _newMaxOracleDelay });
}
/// @notice The ```_setMaximumOracleDelay``` function sets the max oracle delay to determine if Price Feed data is stale
/// @dev Requires the msg.sender to be the timelock address
/// @param _newMaxOracleDelay The new max oracle delay
function setMaximumOracleDelay(uint256 _newMaxOracleDelay) external override {
_requireTimelock();
_setMaximumOracleDelay({ _newMaxOracleDelay: _newMaxOracleDelay });
}
// ====================================================================
// Price Functions
// ====================================================================
/// @notice The ```getEthPerUsdRedStone``` function returns the amount of eth per 1 USD
/// @return _isBadData Whether the data returned from the oracle is stale
/// @return _ethPerUsd The amount of eth per unit of USD
function getEthPerUsdRedStone() public view returns (bool _isBadData, uint256 _ethPerUsd) {
(bool isBadData, , uint256 usdPerEth) = _getEthUsdChainlinkPrice();
_isBadData = isBadData;
_ethPerUsd = (ETH_USD_CHAINLINK_FEED_PRECISION * ORACLE_PRECISION) / usdPerEth;
}
/// @notice The ```getEthPerUsdRedStone``` function returns the amount of eth per 1 USD
/// @return _isBadData Whether the data returned from the oracle is stale
/// @return _ethPerEzEth The amount of eth per unit of USD
function getEthPerEzEthApi3() public view returns (bool _isBadData, uint256 _ethPerEzEth) {
(_isBadData, , _ethPerEzEth) = _getApi3Price();
_ethPerEzEth *= ORACLE_PRECISION / API3_FEED_PRECISION;
}
/// @notice The ```getPricesNormalized``` function returns the normalized prices in human readable form
/// @return _isBadDataNormal If the Redstone oracle is stale
/// @return _priceLowNormal The normalized low price
/// @return _priceHighNormal The normalized high price
function getPricesNormalized()
external
view
returns (bool _isBadDataNormal, uint256 _priceLowNormal, uint256 _priceHighNormal)
{
(bool _isBadData, uint256 _priceLow, uint256 _priceHigh) = _getPrices();
_isBadDataNormal = _isBadData;
_priceLowNormal = NORMALIZATION_0 > 0
? _priceLow * 10 ** uint256(NORMALIZATION_0)
: _priceLow / 10 ** (uint256(-NORMALIZATION_0));
_priceHighNormal = NORMALIZATION_1 > 0
? _priceHigh * 10 ** uint256(NORMALIZATION_1)
: _priceHigh / 10 ** (uint256(-NORMALIZATION_1));
}
function _getPrices() internal view returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh) {
(bool isBadDataRedstone, uint256 _ethPerUsdRedStone) = getEthPerUsdRedStone();
(bool isBadDataApi3, uint256 _ethPerEzEthApi3) = getEthPerEzEthApi3();
uint256 ezEthPerUsd = (ORACLE_PRECISION * _ethPerUsdRedStone) / _ethPerEzEthApi3;
_isBadData = isBadDataRedstone || isBadDataApi3;
_priceLow = _priceHigh = ezEthPerUsd;
}
/// @notice The ```getPrices``` function is intended to return two prices from different oracles
/// @return _isBadData is true when data is stale or otherwise bad
/// @return _priceLow is the lower of the two prices
/// @return _priceHigh is the higher of the two prices
function getPrices() external view returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh) {
return _getPrices();
}
}// SPDX-License-Identifier: ISC
pragma solidity >=0.8.0;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ========================== Timelock2Step ===========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Primary Author
// Drake Evans: https://github.com/DrakeEvans
// Reviewers
// Dennis: https://github.com/denett
// ====================================================================
/// @title Timelock2Step
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @dev Inspired by the OpenZeppelin's Ownable2Step contract
/// @notice An abstract contract which contains 2-step transfer and renounce logic for a timelock address
abstract contract Timelock2Step {
/// @notice The pending timelock address
address public pendingTimelockAddress;
/// @notice The current timelock address
address public timelockAddress;
constructor() {
timelockAddress = msg.sender;
}
/// @notice Emitted when timelock is transferred
error OnlyTimelock();
/// @notice Emitted when pending timelock is transferred
error OnlyPendingTimelock();
/// @notice The ```TimelockTransferStarted``` event is emitted when the timelock transfer is initiated
/// @param previousTimelock The address of the previous timelock
/// @param newTimelock The address of the new timelock
event TimelockTransferStarted(address indexed previousTimelock, address indexed newTimelock);
/// @notice The ```TimelockTransferred``` event is emitted when the timelock transfer is completed
/// @param previousTimelock The address of the previous timelock
/// @param newTimelock The address of the new timelock
event TimelockTransferred(address indexed previousTimelock, address indexed newTimelock);
/// @notice The ```_isSenderTimelock``` function checks if msg.sender is current timelock address
/// @return Whether or not msg.sender is current timelock address
function _isSenderTimelock() internal view returns (bool) {
return msg.sender == timelockAddress;
}
/// @notice The ```_requireTimelock``` function reverts if msg.sender is not current timelock address
function _requireTimelock() internal view {
if (msg.sender != timelockAddress) revert OnlyTimelock();
}
/// @notice The ```_isSenderPendingTimelock``` function checks if msg.sender is pending timelock address
/// @return Whether or not msg.sender is pending timelock address
function _isSenderPendingTimelock() internal view returns (bool) {
return msg.sender == pendingTimelockAddress;
}
/// @notice The ```_requirePendingTimelock``` function reverts if msg.sender is not pending timelock address
function _requirePendingTimelock() internal view {
if (msg.sender != pendingTimelockAddress) revert OnlyPendingTimelock();
}
/// @notice The ```_transferTimelock``` function initiates the timelock transfer
/// @dev This function is to be implemented by a public function
/// @param _newTimelock The address of the nominated (pending) timelock
function _transferTimelock(address _newTimelock) internal {
pendingTimelockAddress = _newTimelock;
emit TimelockTransferStarted(timelockAddress, _newTimelock);
}
/// @notice The ```_acceptTransferTimelock``` function completes the timelock transfer
/// @dev This function is to be implemented by a public function
function _acceptTransferTimelock() internal {
pendingTimelockAddress = address(0);
_setTimelock(msg.sender);
}
/// @notice The ```_setTimelock``` function sets the timelock address
/// @dev This function is to be implemented by a public function
/// @param _newTimelock The address of the new timelock
function _setTimelock(address _newTimelock) internal {
emit TimelockTransferred(timelockAddress, _newTimelock);
timelockAddress = _newTimelock;
}
/// @notice The ```transferTimelock``` function initiates the timelock transfer
/// @dev Must be called by the current timelock
/// @param _newTimelock The address of the nominated (pending) timelock
function transferTimelock(address _newTimelock) external virtual {
_requireTimelock();
_transferTimelock(_newTimelock);
}
/// @notice The ```acceptTransferTimelock``` function completes the timelock transfer
/// @dev Must be called by the pending timelock
function acceptTransferTimelock() external virtual {
_requirePendingTimelock();
_acceptTransferTimelock();
}
/// @notice The ```renounceTimelock``` function renounces the timelock after setting pending timelock to current timelock
/// @dev Pending timelock must be set to current timelock before renouncing, creating a 2-step renounce process
function renounceTimelock() external virtual {
_requireTimelock();
_requirePendingTimelock();
_transferTimelock(address(0));
_setTimelock(address(0));
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;
interface ITimelock2Step {
event TimelockTransferStarted(address indexed previousTimelock, address indexed newTimelock);
event TimelockTransferred(address indexed previousTimelock, address indexed newTimelock);
function acceptTransferTimelock() external;
function pendingTimelockAddress() external view returns (address);
function renounceTimelock() external;
function timelockAddress() external view returns (address);
function transferTimelock(address _newTimelock) external;
}// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ========================== DualOracleBase ==========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Author
// Drake Evans: https://github.com/DrakeEvans
// ====================================================================
import "interfaces/IDualOracle.sol";
struct ConstructorParams {
address baseToken0;
uint8 baseToken0Decimals;
address quoteToken0;
uint8 quoteToken0Decimals;
address baseToken1;
uint8 baseToken1Decimals;
address quoteToken1;
uint8 quoteToken1Decimals;
}
/// @title DualOracleBase
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @notice Base Contract for Frax Dual Oracles
abstract contract DualOracleBase is IDualOracle {
/// @notice The precision of the oracle
uint256 public constant ORACLE_PRECISION = 1e18;
/// @notice The first quote token
address public immutable QUOTE_TOKEN_0;
/// @notice The first quote token decimals
uint256 public immutable QUOTE_TOKEN_0_DECIMALS;
/// @notice The second quote token
address public immutable QUOTE_TOKEN_1;
/// @notice The second quote token decimals
uint256 public immutable QUOTE_TOKEN_1_DECIMALS;
/// @notice The first base token
address public immutable BASE_TOKEN_0;
/// @notice The first base token decimals
uint256 public immutable BASE_TOKEN_0_DECIMALS;
/// @notice The second base token
address public immutable BASE_TOKEN_1;
/// @notice The second base token decimals
uint256 public immutable BASE_TOKEN_1_DECIMALS;
/// @notice The first normalization factor which accounts for different decimals across ERC20s
/// @dev Normalization = quoteTokenDecimals - baseTokenDecimals
int256 public immutable NORMALIZATION_0;
/// @notice The second normalization factor which accounts for different decimals across ERC20s
/// @dev Normalization = quoteTokenDecimals - baseTokenDecimals
int256 public immutable NORMALIZATION_1;
constructor(ConstructorParams memory _params) {
QUOTE_TOKEN_0 = _params.quoteToken0;
QUOTE_TOKEN_0_DECIMALS = _params.quoteToken0Decimals;
QUOTE_TOKEN_1 = _params.quoteToken1;
QUOTE_TOKEN_1_DECIMALS = _params.quoteToken1Decimals;
BASE_TOKEN_0 = _params.baseToken0;
BASE_TOKEN_0_DECIMALS = _params.baseToken0Decimals;
BASE_TOKEN_1 = _params.baseToken1;
BASE_TOKEN_1_DECIMALS = _params.baseToken1Decimals;
NORMALIZATION_0 = int256(QUOTE_TOKEN_0_DECIMALS) - int256(BASE_TOKEN_0_DECIMALS);
NORMALIZATION_1 = int256(QUOTE_TOKEN_1_DECIMALS) - int256(BASE_TOKEN_1_DECIMALS);
}
// ====================================================================
// View Helpers
// ====================================================================
function decimals() external pure returns (uint8) {
return 18;
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface IDualOracle is IERC165 {
function ORACLE_PRECISION() external view returns (uint256);
function BASE_TOKEN_0() external view returns (address);
function BASE_TOKEN_0_DECIMALS() external view returns (uint256);
function BASE_TOKEN_1() external view returns (address);
function BASE_TOKEN_1_DECIMALS() external view returns (uint256);
function decimals() external view returns (uint8);
function getPricesNormalized() external view returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh);
function getPrices() external view returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh);
function name() external view returns (string memory);
function NORMALIZATION_0() external view returns (int256);
function NORMALIZATION_1() external view returns (int256);
function QUOTE_TOKEN_0() external view returns (address);
function QUOTE_TOKEN_0_DECIMALS() external view returns (uint256);
function QUOTE_TOKEN_1() external view returns (address);
function QUOTE_TOKEN_1_DECIMALS() external view returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)
pragma solidity ^0.8.0;
import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
/**
* @dev Storage based implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165Storage is ERC165 {
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ================ EthUsdChainlinkOracleWithMaxDelay =================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Author
// Drake Evans: https://github.com/DrakeEvans
// Reviewers
// Dennis: https://github.com/denett
// ====================================================================
import { AggregatorV3Interface } from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import { ERC165Storage } from "src/contracts/utils/ERC165Storage.sol";
import { IEthUsdChainlinkOracleWithMaxDelay } from "interfaces/oracles/abstracts/IEthUsdChainlinkOracleWithMaxDelay.sol";
struct ConstructorParams {
address ethUsdChainlinkFeedAddress;
uint256 maxEthUsdOracleDelay;
}
/// @title EthUsdChainlinkOracleWithMaxDelay
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @notice An abstract oracle for getting eth/usd prices from Chainlink
abstract contract EthUsdChainlinkOracleWithMaxDelay is ERC165Storage, IEthUsdChainlinkOracleWithMaxDelay {
/// @notice Chainlink aggregator
address public immutable ETH_USD_CHAINLINK_FEED_ADDRESS;
/// @notice Decimals of ETH/USD chainlink feed
uint8 public immutable ETH_USD_CHAINLINK_FEED_DECIMALS;
/// @notice Precision of ETH/USD chainlink feed
uint256 public immutable ETH_USD_CHAINLINK_FEED_PRECISION;
/// @notice Maximum delay of Chainlink data, after which it is considered stale
uint256 public maximumEthUsdOracleDelay;
constructor(ConstructorParams memory _params) {
_registerInterface({ interfaceId: type(IEthUsdChainlinkOracleWithMaxDelay).interfaceId });
ETH_USD_CHAINLINK_FEED_ADDRESS = _params.ethUsdChainlinkFeedAddress;
ETH_USD_CHAINLINK_FEED_DECIMALS = AggregatorV3Interface(ETH_USD_CHAINLINK_FEED_ADDRESS).decimals();
ETH_USD_CHAINLINK_FEED_PRECISION = 10 ** uint256(ETH_USD_CHAINLINK_FEED_DECIMALS);
maximumEthUsdOracleDelay = _params.maxEthUsdOracleDelay;
}
/// @notice The ```_setMaximumEthUsdOracleDelay``` function sets the max oracle delay to determine if Chainlink data is stale
/// @param _newMaxOracleDelay The new max oracle delay
function _setMaximumEthUsdOracleDelay(uint256 _newMaxOracleDelay) internal {
emit SetMaximumEthUsdOracleDelay({
oldMaxOracleDelay: maximumEthUsdOracleDelay,
newMaxOracleDelay: _newMaxOracleDelay
});
maximumEthUsdOracleDelay = _newMaxOracleDelay;
}
function setMaximumEthUsdOracleDelay(uint256 _newMaxOracleDelay) external virtual;
/// @notice The ```_getEthUsdChainlinkPrice``` function is called to get the eth/usd price from Chainlink
/// @dev If data is stale or negative, set bad data to true and return
/// @return _isBadData If the data is stale
/// @return _updatedAt The timestamp of the last update
/// @return _usdPerEth The eth/usd price
function _getEthUsdChainlinkPrice()
internal
view
returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth)
{
(, int256 _answer, , uint256 _ethUsdChainlinkUpdatedAt, ) = AggregatorV3Interface(
ETH_USD_CHAINLINK_FEED_ADDRESS
).latestRoundData();
// If data is stale or negative, set bad data to true and return
_isBadData = _answer <= 0 || ((block.timestamp - _ethUsdChainlinkUpdatedAt) > maximumEthUsdOracleDelay);
_updatedAt = _ethUsdChainlinkUpdatedAt;
_usdPerEth = uint256(_answer);
}
/// @notice The ```getEthUsdChainlinkPrice``` function is called to get the eth/usd price from Chainlink
/// @return _isBadData If the data is stale
/// @return _updatedAt The timestamp of the last update
/// @return _usdPerEth The eth/usd price
function getEthUsdChainlinkPrice()
external
view
virtual
returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth)
{
(_isBadData, _updatedAt, _usdPerEth) = _getEthUsdChainlinkPrice();
}
}// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ===================== Api3OracleWithMaxDelay =======================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// ====================================================================
import { IApi3 } from "src/contracts/interfaces/IApi3PriceFeed.sol";
import { ERC165Storage } from "src/contracts/utils/ERC165Storage.sol";
import { IApi3OracleWithMaxDelay } from "src/contracts/interfaces/oracles/abstracts/IApi3OracleWithMaxDelay.sol";
struct ConstructorParams {
address api3FeedAddress;
uint8 api3FeedDecimals;
uint256 maximumOracleDelay;
}
/// @title Api3OracleWithMaxDelay
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @notice An abstract oracle for getting prices from Api3
abstract contract Api3OracleWithMaxDelay is ERC165Storage, IApi3OracleWithMaxDelay {
/// @notice Api3 Price Feed Address
address public immutable API3_FEED_ADDRESS;
/// @notice Decimals of Api3 feed
uint8 public immutable API3_FEED_DECIMALS;
/// @notice Precision of Api3 feed
uint256 public immutable API3_FEED_PRECISION;
/// @notice Maximum delay of Api3, after which it is considered stale
uint256 public maximumOracleDelay;
constructor(ConstructorParams memory _params) {
_registerInterface({ interfaceId: type(IApi3OracleWithMaxDelay).interfaceId });
API3_FEED_ADDRESS = _params.api3FeedAddress;
API3_FEED_DECIMALS = _params.api3FeedDecimals;
API3_FEED_PRECISION = 10 ** uint256(_params.api3FeedDecimals);
maximumOracleDelay = _params.maximumOracleDelay;
}
/// @notice The ```SetMaximumOracleDelay``` event is emitted when the max oracle delay is set
/// @param oldMaxOracleDelay The old max oracle delay
/// @param newMaxOracleDelay The new max oracle delay
event SetMaximumOracleDelay(uint256 oldMaxOracleDelay, uint256 newMaxOracleDelay);
/// @notice The ```_setMaximumOracleDelay``` function sets the max oracle delay to determine if Price Feed data is stale
/// @param _newMaxOracleDelay The new max oracle delay
function _setMaximumOracleDelay(uint256 _newMaxOracleDelay) internal {
emit SetMaximumOracleDelay({ oldMaxOracleDelay: maximumOracleDelay, newMaxOracleDelay: _newMaxOracleDelay });
maximumOracleDelay = _newMaxOracleDelay;
}
function setMaximumOracleDelay(uint256 _newMaxOracleDelay) external virtual;
function _getApi3Price() internal view returns (bool _isBadData, uint256 _updatedAt, uint256 _price) {
(int224 _answer, uint32 _timestampUpdated) = IApi3(API3_FEED_ADDRESS).read();
// If data is stale or negative, set bad data to true and return
_isBadData = _answer <= 0 || ((block.timestamp - _timestampUpdated) > maximumOracleDelay);
if (_answer <= 0) revert AnswerWouldOverflow();
_updatedAt = _timestampUpdated;
_price = uint256(int256(_answer));
}
/// @notice The ```getApi3Price``` function returns the Api3 price and the timestamp of the last update
/// @dev Uses the same prevision as the Api3 feed, virtual so it can be overridden
/// @return _isBadData True if the data is stale or negative
/// @return _updatedAt The timestamp of the last update
/// @return _price The price
function getApi3Price() external view virtual returns (bool _isBadData, uint256 _updatedAt, uint256 _price) {
return _getApi3Price();
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// 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: UNLICENSED
pragma solidity 0.8.20;
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface IEthUsdChainlinkOracleWithMaxDelay is IERC165 {
event SetMaximumEthUsdOracleDelay(uint256 oldMaxOracleDelay, uint256 newMaxOracleDelay);
function ETH_USD_CHAINLINK_FEED_ADDRESS() external view returns (address);
function ETH_USD_CHAINLINK_FEED_DECIMALS() external view returns (uint8);
function ETH_USD_CHAINLINK_FEED_PRECISION() external view returns (uint256);
function maximumEthUsdOracleDelay() external view returns (uint256);
function getEthUsdChainlinkPrice() external view returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth);
function setMaximumEthUsdOracleDelay(uint256 _newMaxOracleDelay) external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;
interface IApi3 {
function read() external view returns (int224, uint32);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface IApi3OracleWithMaxDelay is IERC165 {
event SetMaximumOracleDelay(address oracle, uint256 oldMaxOracleDelay, uint256 newMaxOracleDelay);
function API3_FEED_ADDRESS() external view returns (address);
function API3_FEED_DECIMALS() external view returns (uint8);
function API3_FEED_PRECISION() external view returns (uint256);
function getApi3Price() external view returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth);
function maximumOracleDelay() external view returns (uint256);
function setMaximumOracleDelay(uint256 _newMaxOracleDelay) external;
error AnswerWouldOverflow();
}{
"remappings": [
"ds-test/=node_modules/ds-test/src/",
"forge-std/=node_modules/forge-std/src/",
"frax-std/=node_modules/frax-standard-solidity/src/",
"script/=src/script/",
"src/=src/",
"test/=src/test/",
"interfaces/=src/contracts/interfaces/",
"arbitrum/=node_modules/@arbitrum/",
"rlp/=node_modules/solidity-rlp/contracts/",
"@solmate/=node_modules/@rari-capital/solmate/src/",
"@arbitrum/=node_modules/@arbitrum/",
"@chainlink/=node_modules/@chainlink/",
"@mean-finance/=node_modules/@mean-finance/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@rari-capital/=node_modules/@rari-capital/",
"@uniswap/=node_modules/@uniswap/",
"dev-fraxswap/=node_modules/dev-fraxswap/",
"frax-standard-solidity/=node_modules/frax-standard-solidity/",
"prb-math/=node_modules/prb-math/",
"solidity-bytes-utils/=node_modules/solidity-bytes-utils/",
"solidity-rlp/=node_modules/solidity-rlp/"
],
"optimizer": {
"enabled": true,
"runs": 1000000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"components":[{"internalType":"address","name":"ezEthErc20","type":"address"},{"internalType":"address","name":"timelockAddress","type":"address"},{"internalType":"address","name":"ethUsdFeedAddress","type":"address"},{"internalType":"uint256","name":"ethUsdMaxOracleDelay","type":"uint256"},{"internalType":"address","name":"api3PriceFeed","type":"address"},{"internalType":"uint8","name":"api3FeedDecimals","type":"uint8"},{"internalType":"uint256","name":"maximumOracleDelayApi3","type":"uint256"}],"internalType":"struct ConstructorParams","name":"_params","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AnswerWouldOverflow","type":"error"},{"inputs":[],"name":"OnlyPendingTimelock","type":"error"},{"inputs":[],"name":"OnlyTimelock","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxOracleDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxOracleDelay","type":"uint256"}],"name":"SetMaximumEthUsdOracleDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxOracleDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxOracleDelay","type":"uint256"}],"name":"SetMaximumOracleDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oracle","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldMaxOracleDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxOracleDelay","type":"uint256"}],"name":"SetMaximumOracleDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferred","type":"event"},{"inputs":[],"name":"API3_FEED_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"API3_FEED_DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"API3_FEED_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_TOKEN_0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_TOKEN_0_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_TOKEN_1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_TOKEN_1_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_CHAINLINK_FEED_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_CHAINLINK_FEED_DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_CHAINLINK_FEED_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EZETH_ERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NORMALIZATION_0","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NORMALIZATION_1","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUOTE_TOKEN_0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUOTE_TOKEN_0_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUOTE_TOKEN_1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUOTE_TOKEN_1_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptTransferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getApi3Price","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_updatedAt","type":"uint256"},{"internalType":"uint256","name":"_price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEthPerEzEthApi3","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_ethPerEzEth","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEthPerUsdRedStone","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_ethPerUsd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEthUsdChainlinkPrice","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_updatedAt","type":"uint256"},{"internalType":"uint256","name":"_usdPerEth","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrices","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_priceLow","type":"uint256"},{"internalType":"uint256","name":"_priceHigh","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPricesNormalized","outputs":[{"internalType":"bool","name":"_isBadDataNormal","type":"bool"},{"internalType":"uint256","name":"_priceLowNormal","type":"uint256"},{"internalType":"uint256","name":"_priceHighNormal","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumEthUsdOracleDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumOracleDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"pendingTimelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxOracleDelay","type":"uint256"}],"name":"setMaximumEthUsdOracleDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxOracleDelay","type":"uint256"}],"name":"setMaximumOracleDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newTimelock","type":"address"}],"name":"transferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6102a06040523480156200001257600080fd5b506040516200191d3803806200191d833981016040819052620000359162000392565b604080518082018252828201516001600160a01b039081168252606080850151602080850191909152845180830186526080808801518516825260a08089015160ff9081168486015260c0808b0151858b015289516101008082018c5261034880835260129883018981528e518c169d84018e90529983018981528388019182528387018a81528f518d1685870190815260e08087019c8d529f909952905186169687905296518b1690935296518316909a52895188169095529451851661012081905293519095166101405251909216610160529293909290916200011c919062000466565b610180526101605160e05162000133919062000466565b6101a05250600180546001600160a01b031916331790556200015c630db3a68d60e31b62000283565b80516001600160a01b03166101c05260208101805160ff9081166101e05290516200018a9116600a6200058f565b6102005260400151600355620001a76323e2f2e160e11b62000283565b80516001600160a01b03166102208190526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa158015620001f4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021a9190620005a4565b60ff166102408190526200023090600a6200058f565b610260526020908101516004558101516200024b9062000307565b6200025d63415f130360e01b62000283565b6200026f632fa3fc3160e21b62000283565b516001600160a01b031661028052620005c2565b6001600160e01b03198082169003620002e25760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319166000908152600260205260409020805460ff19166001179055565b6001546040516001600160a01b038084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc690600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b80516001600160a01b03811681146200037b57600080fd5b919050565b805160ff811681146200037b57600080fd5b600060e08284031215620003a557600080fd5b60405160e081016001600160401b0381118282101715620003d657634e487b7160e01b600052604160045260246000fd5b604052620003e48362000363565b8152620003f46020840162000363565b6020820152620004076040840162000363565b604082015260608301516060820152620004246080840162000363565b60808201526200043760a0840162000380565b60a082015260c083015160c08201528091505092915050565b634e487b7160e01b600052601160045260246000fd5b818103600083128015838313168383128216171562000489576200048962000450565b5092915050565b600181815b80851115620004d1578160001904821115620004b557620004b562000450565b80851615620004c357918102915b93841c939080029062000495565b509250929050565b600082620004ea5750600162000589565b81620004f95750600062000589565b81600181146200051257600281146200051d576200053d565b600191505062000589565b60ff84111562000531576200053162000450565b50506001821b62000589565b5060208310610133831016604e8410600b841016171562000562575081810a62000589565b6200056e838362000490565b806000190482111562000585576200058562000450565b0290505b92915050565b60006200059d8383620004d9565b9392505050565b600060208284031215620005b757600080fd5b6200059d8262000380565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e051610200516102205161024051610260516102805161124c620006d160003960006102c20152600081816104fd015261091a0152600061041e01526000818161055c0152610a0b0152600081816103d00152610985015260006105c10152600081816106940152610cd00152600081816102650152818161082c01528181610855015261089801526000818161059a0152818161078a015281816107b301526107f6015260006103f701526000610394015260006106650152600061036d01526000610524015260006104ce0152600061063e01526000610617015261124c6000f3fe608060405234801561001057600080fd5b506004361061025b5760003560e01c8063702dae3f11610145578063cbe13bcf116100bd578063e0d2e7801161008c578063f097486c11610071578063f097486c14610660578063f6ccaad414610687578063ff8e2dd81461068f57600080fd5b8063e0d2e78014610612578063e5a66dfa1461063957600080fd5b8063cbe13bcf146105bc578063cede91a4146105e3578063d2333be7146105ec578063d7360946146105ff57600080fd5b806397d59a6c116101145780639c0d313f116100f95780639c0d313f1461057e578063bd9a548b1461058d578063c82f2b121461059557600080fd5b806397d59a6c1461054f57806399a64f281461055757600080fd5b8063702dae3f146104f0578063726de1a5146104f8578063781097d01461051f5780637c99a4991461054657600080fd5b806337f85f66116101d85780634bc66f32116101a75780634f8b4ae71161018c5780634f8b4ae7146104a2578063550af47e146104aa57806359c909e1146104c957600080fd5b80634bc66f321461047a5780634d3375e81461049a57600080fd5b806337f85f66146103f25780633b17136a146104195780633cb6f5fa14610440578063450140951461046557600080fd5b8063090f3f501161022f5780632088800411610214578063208880041461038f578063313ce567146103b657806335322603146103cb57600080fd5b8063090f3f5014610348578063116d79761461036857600080fd5b806232e91a1461026057806301ffc9a71461029a5780630342bd5b146102bd57806306fdde0314610309575b600080fd5b6102877f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6102ad6102a8366004610e8b565b6106b6565b6040519015158152602001610291565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610291565b604080518082018252601c81527f457a4574682041706933202b2052656473746f6e65204f7261636c6500000000602082015290516102919190610ed4565b6000546102e49073ffffffffffffffffffffffffffffffffffffffff1681565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b60125b60405160ff9091168152602001610291565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b61044861073f565b604080519315158452602084019290925290820152606001610291565b610478610473366004610f40565b610758565b005b6001546102e49073ffffffffffffffffffffffffffffffffffffffff1681565b61044861076c565b6104786108d2565b6104b26108f8565b604080519215158352602083019190915201610291565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b610448610955565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b61028760045481565b6104b261096d565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b610287670de0b6b3a764000081565b6104486109c2565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b61028760035481565b6104786105fa366004610f76565b6109cf565b61047861060d366004610f76565b6109e0565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b6104786109f1565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061073957507fffffffff00000000000000000000000000000000000000000000000000000000821660009081526002602052604090205460ff165b92915050565b600080600061074c610a01565b91959094509092509050565b610760610ac4565b61076981610b15565b50565b60008060008060008061077d610b8a565b92509250925082955060007f0000000000000000000000000000000000000000000000000000000000000000136107f1576107d77f0000000000000000000000000000000000000000000000000000000000000000610fbe565b6107e290600a611116565b6107ec9083611122565b610826565b61081c7f0000000000000000000000000000000000000000000000000000000000000000600a611116565b610826908361115d565b945060007f000000000000000000000000000000000000000000000000000000000000000013610893576108797f0000000000000000000000000000000000000000000000000000000000000000610fbe565b61088490600a611116565b61088e9082611122565b6108c8565b6108be7f0000000000000000000000000000000000000000000000000000000000000000600a611116565b6108c8908261115d565b9350505050909192565b6108da610ac4565b6108e2610be7565b6108ec6000610b15565b6108f66000610c38565b565b600080600080610906610a01565b925050915081935080670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000000000000610943919061115d565b61094d9190611122565b925050509091565b6000806000610962610cc6565b925092509250909192565b600080610978610cc6565b9193509091506109b290507f0000000000000000000000000000000000000000000000000000000000000000670de0b6b3a7640000611122565b6109bc908261115d565b90509091565b6000806000610962610b8a565b6109d7610ac4565b61076981610dd8565b6109e8610ac4565b61076981610e19565b6109f9610be7565b6108f6610e5a565b60008060008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610a74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a989190611193565b50935050925050600082131580610ab95750600454610ab782426111e3565b115b959094509092509050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146108f6576040517f1c0be90a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a9190a350565b6000806000806000610b9a6108f8565b91509150600080610ba961096d565b9092509050600081610bc385670de0b6b3a764000061115d565b610bcd9190611122565b90508480610bd85750825b98909750879650945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108f6576040517ff5c49e6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc690600090a3600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60008060008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166357de26a46040518163ffffffff1660e01b81526004016040805180830381865afa158015610d38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5c91906111f6565b91509150600082601b0b131580610d835750600354610d8163ffffffff8316426111e3565b115b9450600082601b0b13610dc2576040517fbdd1ee7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8063ffffffff16935081601b0b92505050909192565b60035460408051918252602082018390527fd72ef688fa430b6a285b84371ba35e8a8e0762b32c1deb7be9d9c111ca79f5ea910160405180910390a1600355565b60045460408051918252602082018390527f1b427db70b2e813aae1e9f4dc54fcd2ae904b1350f60b84a7bab7d379aa2b02e910160405180910390a1600455565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556108f633610c38565b600060208284031215610e9d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ecd57600080fd5b9392505050565b600060208083528351808285015260005b81811015610f0157858101830151858201604001528201610ee5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600060208284031215610f5257600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610ecd57600080fd5b600060208284031215610f8857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203610fef57610fef610f8f565b5060000390565b600181815b8085111561104f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561103557611035610f8f565b8085161561104257918102915b93841c9390800290610ffb565b509250929050565b60008261106657506001610739565b8161107357506000610739565b81600181146110895760028114611093576110af565b6001915050610739565b60ff8411156110a4576110a4610f8f565b50506001821b610739565b5060208310610133831016604e8410600b84101617156110d2575081810a610739565b6110dc8383610ff6565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561110e5761110e610f8f565b029392505050565b6000610ecd8383611057565b600082611158577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761073957610739610f8f565b805169ffffffffffffffffffff8116811461118e57600080fd5b919050565b600080600080600060a086880312156111ab57600080fd5b6111b486611174565b94506020860151935060408601519250606086015191506111d760808701611174565b90509295509295909350565b8181038181111561073957610739610f8f565b6000806040838503121561120957600080fd5b825180601b0b811461121a57600080fd5b602084015190925063ffffffff8116811461123457600080fd5b80915050925092905056fea164736f6c6343000814000a0000000000000000000000002416092f143378750bb29b79ed961ab195cceea5000000000000000000000000c16068d1ca7e24e20e56bb70af4d00d92aa4f0b200000000000000000000000089e60b56efd70a1d4fbbae947bc33cae41e37a72000000000000000000000000000000000000000000000000000000000000558c0000000000000000000000003621b06bffe478eb481adf65bbf139a052ed7321000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000152ac
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061025b5760003560e01c8063702dae3f11610145578063cbe13bcf116100bd578063e0d2e7801161008c578063f097486c11610071578063f097486c14610660578063f6ccaad414610687578063ff8e2dd81461068f57600080fd5b8063e0d2e78014610612578063e5a66dfa1461063957600080fd5b8063cbe13bcf146105bc578063cede91a4146105e3578063d2333be7146105ec578063d7360946146105ff57600080fd5b806397d59a6c116101145780639c0d313f116100f95780639c0d313f1461057e578063bd9a548b1461058d578063c82f2b121461059557600080fd5b806397d59a6c1461054f57806399a64f281461055757600080fd5b8063702dae3f146104f0578063726de1a5146104f8578063781097d01461051f5780637c99a4991461054657600080fd5b806337f85f66116101d85780634bc66f32116101a75780634f8b4ae71161018c5780634f8b4ae7146104a2578063550af47e146104aa57806359c909e1146104c957600080fd5b80634bc66f321461047a5780634d3375e81461049a57600080fd5b806337f85f66146103f25780633b17136a146104195780633cb6f5fa14610440578063450140951461046557600080fd5b8063090f3f501161022f5780632088800411610214578063208880041461038f578063313ce567146103b657806335322603146103cb57600080fd5b8063090f3f5014610348578063116d79761461036857600080fd5b806232e91a1461026057806301ffc9a71461029a5780630342bd5b146102bd57806306fdde0314610309575b600080fd5b6102877f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6102ad6102a8366004610e8b565b6106b6565b6040519015158152602001610291565b6102e47f0000000000000000000000002416092f143378750bb29b79ed961ab195cceea581565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610291565b604080518082018252601c81527f457a4574682041706933202b2052656473746f6e65204f7261636c6500000000602082015290516102919190610ed4565b6000546102e49073ffffffffffffffffffffffffffffffffffffffff1681565b6102e47f000000000000000000000000000000000000000000000000000000000000034881565b6102e47f000000000000000000000000000000000000000000000000000000000000034881565b60125b60405160ff9091168152602001610291565b6102877f0000000000000000000000000000000000000000000000000de0b6b3a764000081565b6102877f000000000000000000000000000000000000000000000000000000000000001281565b6103b97f000000000000000000000000000000000000000000000000000000000000000881565b61044861073f565b604080519315158452602084019290925290820152606001610291565b610478610473366004610f40565b610758565b005b6001546102e49073ffffffffffffffffffffffffffffffffffffffff1681565b61044861076c565b6104786108d2565b6104b26108f8565b604080519215158352602083019190915201610291565b6102e47f0000000000000000000000002416092f143378750bb29b79ed961ab195cceea581565b610448610955565b6102877f0000000000000000000000000000000000000000000000000000000005f5e10081565b6102877f000000000000000000000000000000000000000000000000000000000000001281565b61028760045481565b6104b261096d565b6102e47f00000000000000000000000089e60b56efd70a1d4fbbae947bc33cae41e37a7281565b610287670de0b6b3a764000081565b6104486109c2565b6102877f000000000000000000000000000000000000000000000000000000000000000081565b6103b97f000000000000000000000000000000000000000000000000000000000000001281565b61028760035481565b6104786105fa366004610f76565b6109cf565b61047861060d366004610f76565b6109e0565b6102e47f0000000000000000000000002416092f143378750bb29b79ed961ab195cceea581565b6102877f000000000000000000000000000000000000000000000000000000000000001281565b6102877f000000000000000000000000000000000000000000000000000000000000001281565b6104786109f1565b6102e47f0000000000000000000000003621b06bffe478eb481adf65bbf139a052ed732181565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061073957507fffffffff00000000000000000000000000000000000000000000000000000000821660009081526002602052604090205460ff165b92915050565b600080600061074c610a01565b91959094509092509050565b610760610ac4565b61076981610b15565b50565b60008060008060008061077d610b8a565b92509250925082955060007f0000000000000000000000000000000000000000000000000000000000000000136107f1576107d77f0000000000000000000000000000000000000000000000000000000000000000610fbe565b6107e290600a611116565b6107ec9083611122565b610826565b61081c7f0000000000000000000000000000000000000000000000000000000000000000600a611116565b610826908361115d565b945060007f000000000000000000000000000000000000000000000000000000000000000013610893576108797f0000000000000000000000000000000000000000000000000000000000000000610fbe565b61088490600a611116565b61088e9082611122565b6108c8565b6108be7f0000000000000000000000000000000000000000000000000000000000000000600a611116565b6108c8908261115d565b9350505050909192565b6108da610ac4565b6108e2610be7565b6108ec6000610b15565b6108f66000610c38565b565b600080600080610906610a01565b925050915081935080670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000005f5e100610943919061115d565b61094d9190611122565b925050509091565b6000806000610962610cc6565b925092509250909192565b600080610978610cc6565b9193509091506109b290507f0000000000000000000000000000000000000000000000000de0b6b3a7640000670de0b6b3a7640000611122565b6109bc908261115d565b90509091565b6000806000610962610b8a565b6109d7610ac4565b61076981610dd8565b6109e8610ac4565b61076981610e19565b6109f9610be7565b6108f6610e5a565b60008060008060007f00000000000000000000000089e60b56efd70a1d4fbbae947bc33cae41e37a7273ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610a74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a989190611193565b50935050925050600082131580610ab95750600454610ab782426111e3565b115b959094509092509050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146108f6576040517f1c0be90a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a9190a350565b6000806000806000610b9a6108f8565b91509150600080610ba961096d565b9092509050600081610bc385670de0b6b3a764000061115d565b610bcd9190611122565b90508480610bd85750825b98909750879650945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146108f6576040517ff5c49e6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc690600090a3600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60008060008060007f0000000000000000000000003621b06bffe478eb481adf65bbf139a052ed732173ffffffffffffffffffffffffffffffffffffffff166357de26a46040518163ffffffff1660e01b81526004016040805180830381865afa158015610d38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5c91906111f6565b91509150600082601b0b131580610d835750600354610d8163ffffffff8316426111e3565b115b9450600082601b0b13610dc2576040517fbdd1ee7d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8063ffffffff16935081601b0b92505050909192565b60035460408051918252602082018390527fd72ef688fa430b6a285b84371ba35e8a8e0762b32c1deb7be9d9c111ca79f5ea910160405180910390a1600355565b60045460408051918252602082018390527f1b427db70b2e813aae1e9f4dc54fcd2ae904b1350f60b84a7bab7d379aa2b02e910160405180910390a1600455565b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556108f633610c38565b600060208284031215610e9d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ecd57600080fd5b9392505050565b600060208083528351808285015260005b81811015610f0157858101830151858201604001528201610ee5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600060208284031215610f5257600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610ecd57600080fd5b600060208284031215610f8857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007f80000000000000000000000000000000000000000000000000000000000000008203610fef57610fef610f8f565b5060000390565b600181815b8085111561104f57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561103557611035610f8f565b8085161561104257918102915b93841c9390800290610ffb565b509250929050565b60008261106657506001610739565b8161107357506000610739565b81600181146110895760028114611093576110af565b6001915050610739565b60ff8411156110a4576110a4610f8f565b50506001821b610739565b5060208310610133831016604e8410600b84101617156110d2575081810a610739565b6110dc8383610ff6565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561110e5761110e610f8f565b029392505050565b6000610ecd8383611057565b600082611158577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b808202811582820484141761073957610739610f8f565b805169ffffffffffffffffffff8116811461118e57600080fd5b919050565b600080600080600060a086880312156111ab57600080fd5b6111b486611174565b94506020860151935060408601519250606086015191506111d760808701611174565b90509295509295909350565b8181038181111561073957610739610f8f565b6000806040838503121561120957600080fd5b825180601b0b811461121a57600080fd5b602084015190925063ffffffff8116811461123457600080fd5b80915050925092905056fea164736f6c6343000814000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000002416092f143378750bb29b79ed961ab195cceea5000000000000000000000000c16068d1ca7e24e20e56bb70af4d00d92aa4f0b200000000000000000000000089e60b56efd70a1d4fbbae947bc33cae41e37a72000000000000000000000000000000000000000000000000000000000000558c0000000000000000000000003621b06bffe478eb481adf65bbf139a052ed7321000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000152ac
-----Decoded View---------------
Arg [0] : _params (tuple):
Arg [1] : ezEthErc20 (address): 0x2416092f143378750bb29b79eD961ab195CcEea5
Arg [2] : timelockAddress (address): 0xc16068d1ca7E24E20e56bB70af4D00D92AA4f0b2
Arg [3] : ethUsdFeedAddress (address): 0x89e60b56efD70a1D4FBBaE947bC33cae41e37A72
Arg [4] : ethUsdMaxOracleDelay (uint256): 21900
Arg [5] : api3PriceFeed (address): 0x3621b06BfFE478eB481adf65bbF139A052Ed7321
Arg [6] : api3FeedDecimals (uint8): 18
Arg [7] : maximumOracleDelayApi3 (uint256): 86700
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000002416092f143378750bb29b79ed961ab195cceea5
Arg [1] : 000000000000000000000000c16068d1ca7e24e20e56bb70af4d00d92aa4f0b2
Arg [2] : 00000000000000000000000089e60b56efd70a1d4fbbae947bc33cae41e37a72
Arg [3] : 000000000000000000000000000000000000000000000000000000000000558c
Arg [4] : 0000000000000000000000003621b06bffe478eb481adf65bbf139a052ed7321
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [6] : 00000000000000000000000000000000000000000000000000000000000152ac
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.