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
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers. Name tag integration is not available in advanced view.
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
||||
---|---|---|---|---|---|---|---|
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21877005 | 7 hrs ago | 0 ETH | |||||
21864746 | 2 days ago | 0 ETH | |||||
21864746 | 2 days ago | 0 ETH | |||||
21864746 | 2 days ago | 0 ETH | |||||
21864746 | 2 days ago | 0 ETH | |||||
21864746 | 2 days ago | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
FxEzETHOracleV2
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity =0.8.20; import { Math } from "@openzeppelin/contracts-v4/utils/math/Math.sol"; import { IFxRateProvider } from "../../interfaces/f(x)/IFxRateProvider.sol"; import { IBalancerPool } from "../../interfaces/IBalancerPool.sol"; import { ITwapOracle } from "../../price-oracle/interfaces/ITwapOracle.sol"; import { FxSpotOracleBase } from "./FxSpotOracleBase.sol"; import { FxLSDOracleV2Base } from "./FxLSDOracleV2Base.sol"; contract FxEzETHOracleV2 is FxLSDOracleV2Base { /************* * Constants * *************/ /// @dev The address of ezETH token. address internal constant ezETH = 0xbf5495Efe5DB9ce00f80364C8B423567e58d2110; /// @dev The address of Balancer V2 pool with ezETH. address public immutable Balancer_ezETH_Pool; /// @notice The address of the RedStone ezETH/ETH Twap. address public immutable RedStone_ezETH_ETH_Twap; /*************** * Constructor * ***************/ constructor( address _spotPriceOracle, bytes32 _Chainlink_ETH_USD_Spot, address _Chainlink_ETH_USD_Twap, address _Balancer_ezETH_Pool, address _RedStone_ezETH_ETH_Twap ) FxSpotOracleBase(_spotPriceOracle) FxLSDOracleV2Base(_Chainlink_ETH_USD_Spot, _Chainlink_ETH_USD_Twap) { Balancer_ezETH_Pool = _Balancer_ezETH_Pool; RedStone_ezETH_ETH_Twap = _RedStone_ezETH_ETH_Twap; } /********************** * Internal Functions * **********************/ /// @inheritdoc FxLSDOracleV2Base /// @dev [RedStone ezETH/ETH twap] * [Chainlink ETH/USD twap] / ezETHRateProvider.getRate() function _getLSDUSDTwap() internal view virtual override returns (uint256) { uint256 ezETH_ETH_RedStoneTwap = ITwapOracle(RedStone_ezETH_ETH_Twap).getTwap(block.timestamp); uint256 ETH_USD_ChainlinkTwap = _getETHUSDTwap(); (uint256 rate, , , ) = IBalancerPool(Balancer_ezETH_Pool).getTokenRateCache(ezETH); unchecked { return (ezETH_ETH_RedStoneTwap * ETH_USD_ChainlinkTwap) / rate; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/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 (last updated v4.9.0) (access/Ownable2Step.sol) pragma solidity ^0.8.0; import "./Ownable.sol"; /** * @dev Contract module which provides 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} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2Step is Ownable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } }
// 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT pragma solidity =0.8.20; import { Math } from "@openzeppelin/contracts-v4/utils/math/Math.sol"; import { FxSpotOracleBase } from "./FxSpotOracleBase.sol"; import { IFxPriceOracleV2 } from "../../interfaces/f(x)/IFxPriceOracleV2.sol"; import { ITwapOracle } from "../../price-oracle/interfaces/ITwapOracle.sol"; abstract contract FxLSDOracleV2Base is FxSpotOracleBase, IFxPriceOracleV2 { /************* * Constants * *************/ /// @notice The Chainlink ETH/USD price feed. /// @dev See comments of `_readSpotPriceByChainlink` for more details. bytes32 public immutable Chainlink_ETH_USD_Spot; /// @notice The address of the Chainlink ETH/USD Twap. address public immutable Chainlink_ETH_USD_Twap; /************* * Variables * *************/ /// @dev The encodings for ETH/USD spot sources. bytes private onchainSpotEncodings_ETHUSD; /// @dev The encodings for LSD/ETH spot sources. bytes private onchainSpotEncodings_LSDETH; /// @dev The encodings for LSD/USD spot sources. bytes private onchainSpotEncodings_LSDUSD; /// @notice The value of maximum price deviation, multiplied by 1e18. uint256 public maxPriceDeviation; /*************** * Constructor * ***************/ constructor(bytes32 _Chainlink_ETH_USD_Spot, address _Chainlink_ETH_USD_Twap) { Chainlink_ETH_USD_Spot = _Chainlink_ETH_USD_Spot; Chainlink_ETH_USD_Twap = _Chainlink_ETH_USD_Twap; _updateMaxPriceDeviation(1e16); // 1% } /************************* * Public View Functions * *************************/ /// @notice Return the ETH/USD spot price. /// @return chainlinkPrice The spot price from Chainlink price feed. /// @return minPrice The minimum spot price among all available sources. /// @return maxPrice The maximum spot price among all available sources. function getETHUSDSpotPrice() external view returns ( uint256 chainlinkPrice, uint256 minPrice, uint256 maxPrice ) { (chainlinkPrice, minPrice, maxPrice) = _getETHUSDSpotPrice(); } /// @notice Return the ETH/USD spot prices. /// @return prices The list of spot price among all available sources, multiplied by 1e18. function getETHUSDSpotPrices() external view returns (uint256[] memory prices) { prices = _getSpotPriceByEncoding(onchainSpotEncodings_ETHUSD); } /// @notice Return the LSD/ETH spot prices. /// @return prices The list of spot price among all available sources, multiplied by 1e18. function getLSDETHSpotPrices() public view returns (uint256[] memory prices) { prices = _getSpotPriceByEncoding(onchainSpotEncodings_LSDETH); } /// @notice Return the LSD/ETH spot prices. /// @return prices The list of spot price among all available sources, multiplied by 1e18. function getLSDUSDSpotPrices() public view returns (uint256[] memory prices) { prices = _getSpotPriceByEncoding(onchainSpotEncodings_LSDUSD); } /// @notice Return the ETH/USD time-weighted average price. /// @return price The time-weighted average price, multiplied by 1e18. function getETHUSDTwap() external view returns (uint256 price) { price = _getETHUSDTwap(); } /// @notice Return the LSD/USD time-weighted average price. /// @return price The time-weighted average price, multiplied by 1e18. function getLSDUSDTwap() external view returns (uint256 price) { price = _getLSDUSDTwap(); } /// @inheritdoc IFxPriceOracleV2 /// @dev The price is valid iff |maxPrice-minPrice|/minPrice < maxPriceDeviation function getPrice() external view override returns ( bool isValid, uint256 twap, uint256 minPrice, uint256 maxPrice ) { twap = _getLSDUSDTwap(); (minPrice, maxPrice) = _getLSDMinMaxPrice(twap); unchecked { isValid = (maxPrice - minPrice) * PRECISION < maxPriceDeviation * minPrice; } } /************************ * Restricted Functions * ************************/ /// @notice Update the on-chain spot encodings. /// @param encodings The encodings to update. See `_getSpotPriceByEncoding` for more details. /// @param spotType The type of the encodings. function updateOnchainSpotEncodings(bytes memory encodings, uint256 spotType) external onlyOwner { // validate encoding uint256[] memory prices = _getSpotPriceByEncoding(encodings); if (spotType == 0) { onchainSpotEncodings_ETHUSD = encodings; if (prices.length == 0) revert ErrorInvalidEncodings(); } else if (spotType == 1) { onchainSpotEncodings_LSDETH = encodings; } else if (spotType == 2) { onchainSpotEncodings_LSDUSD = encodings; } } /// @notice Update the value of maximum price deviation. /// @param newMaxPriceDeviation The new value of maximum price deviation, multiplied by 1e18. function updateMaxPriceDeviation(uint256 newMaxPriceDeviation) external onlyOwner { _updateMaxPriceDeviation(newMaxPriceDeviation); } /********************** * Internal Functions * **********************/ /// @dev Internal function to update the value of maximum price deviation. /// @param newMaxPriceDeviation The new value of maximum price deviation, multiplied by 1e18. function _updateMaxPriceDeviation(uint256 newMaxPriceDeviation) private { uint256 oldMaxPriceDeviation = maxPriceDeviation; maxPriceDeviation = newMaxPriceDeviation; emit UpdateMaxPriceDeviation(oldMaxPriceDeviation, newMaxPriceDeviation); } /// @dev Internal function to calculate the ETH/USD spot price. /// @return chainlinkPrice The spot price from Chainlink price feed, multiplied by 1e18. /// @return minPrice The minimum spot price among all available sources, multiplied by 1e18. /// @return maxPrice The maximum spot price among all available sources, multiplied by 1e18. function _getETHUSDSpotPrice() internal view returns ( uint256 chainlinkPrice, uint256 minPrice, uint256 maxPrice ) { chainlinkPrice = _readSpotPriceByChainlink(Chainlink_ETH_USD_Spot); uint256[] memory prices = _getSpotPriceByEncoding(onchainSpotEncodings_ETHUSD); minPrice = maxPrice = chainlinkPrice; for (uint256 i = 0; i < prices.length; i++) { if (prices[i] > maxPrice) maxPrice = prices[i]; if (prices[i] < minPrice) minPrice = prices[i]; } } /// @dev Internal function to return the ETH/USD time-weighted average price. /// @return price The time-weighted average price of ETH/USD, multiplied by 1e18. function _getETHUSDTwap() internal view returns (uint256 price) { price = ITwapOracle(Chainlink_ETH_USD_Twap).getTwap(block.timestamp); } /// @dev Internal function to return the min/max LSD/USD prices. /// @param twap The LSD/USD time-weighted average price, multiplied by 1e18. /// @return minPrice The minimum price among all available sources (including twap), multiplied by 1e18. /// @return maxPrice The maximum price among all available sources (including twap), multiplied by 1e18. function _getLSDMinMaxPrice(uint256 twap) internal view returns (uint256 minPrice, uint256 maxPrice) { minPrice = maxPrice = twap; (, uint256 minETHUSDPrice, uint256 maxETHUSDPrice) = _getETHUSDSpotPrice(); uint256[] memory LSD_ETH_prices = getLSDETHSpotPrices(); uint256[] memory LSD_USD_prices = getLSDUSDSpotPrices(); uint256 length = LSD_ETH_prices.length; uint256 LSD_ETH_minPrice = type(uint256).max; uint256 LSD_ETH_maxPrice; unchecked { for (uint256 i = 0; i < length; i++) { uint256 price = LSD_ETH_prices[i]; if (price > LSD_ETH_maxPrice) LSD_ETH_maxPrice = price; if (price < LSD_ETH_minPrice) LSD_ETH_minPrice = price; } if (LSD_ETH_maxPrice != 0) { minPrice = Math.min(minPrice, (LSD_ETH_minPrice * minETHUSDPrice) / PRECISION); maxPrice = Math.max(maxPrice, (LSD_ETH_maxPrice * maxETHUSDPrice) / PRECISION); } length = LSD_USD_prices.length; for (uint256 i = 0; i < length; i++) { uint256 price = LSD_USD_prices[i]; if (price > maxPrice) maxPrice = price; if (price < minPrice) minPrice = price; } } } /// @dev Internal function to return the LSD/USD time-weighted average price. /// @return price The time-weighted average price of LSD/USD, multiplied by 1e18. function _getLSDUSDTwap() internal view virtual returns (uint256 price); }
// SPDX-License-Identifier: MIT pragma solidity =0.8.20; import { Ownable2Step } from "@openzeppelin/contracts-v4/access/Ownable2Step.sol"; import { AggregatorV3Interface } from "../../price-oracle/interfaces/AggregatorV3Interface.sol"; import { ISpotPriceOracle } from "../../price-oracle/interfaces/ISpotPriceOracle.sol"; abstract contract FxSpotOracleBase is Ownable2Step { /********** * Errors * **********/ /// @dev Thrown when the given encodings are invalid. error ErrorInvalidEncodings(); /************* * Constants * *************/ /// @dev The precision for oracle price. uint256 internal constant PRECISION = 1e18; /// @dev The address of `SpotPriceOracle` contract. address immutable spotPriceOracle; /*************** * Constructor * ***************/ constructor(address _spotPriceOracle) { spotPriceOracle = _spotPriceOracle; } /********************** * Internal Functions * **********************/ /// @dev The encoding is below. /// ```text /// | 32 bits | 64 bits | 160 bits | /// | heartbeat | scale | price_feed | /// |low high | /// ``` function _readSpotPriceByChainlink(bytes32 encoding) internal view returns (uint256) { address aggregator; uint256 scale; uint256 heartbeat; assembly { aggregator := shr(96, encoding) scale := and(shr(32, encoding), 0xffffffffffffffff) heartbeat := and(encoding, 0xffffffff) } (, int256 answer, , uint256 updatedAt, ) = AggregatorV3Interface(aggregator).latestRoundData(); if (block.timestamp - updatedAt > heartbeat) revert("expired"); return uint256(answer) * scale; } /// @dev Internal function to calculate spot price by encodings. /// /// The details of the encoding is below /// ```text /// | 1 byte | ... | ... | ... | ... | /// | num_source | source[0] | source[1] | ... | source[n] | /// /// source encoding: /// | 1 byte | 32 bytes | 32 bytes | ... | 32 bytes | /// | num_pool | pool[0] | pool[1] | ... | pool[n] | /// 1 <= num_pool <= 3 /// /// The encoding of each pool can be found in `SpotPriceOracle` contract. /// ``` /// @return prices The list of prices of each source, multiplied by 1e18. function _getSpotPriceByEncoding(bytes memory encodings) internal view returns (uint256[] memory prices) { uint256 ptr; uint256 length; assembly { ptr := add(encodings, 0x21) length := byte(0, mload(sub(ptr, 1))) } prices = new uint256[](length); for (uint256 i = 0; i < length; i++) { uint256 encoding1; uint256 encoding2; uint256 encoding3; assembly { let cnt := byte(0, mload(ptr)) ptr := add(ptr, 0x01) if gt(cnt, 0) { encoding1 := mload(ptr) ptr := add(ptr, 0x20) } if gt(cnt, 1) { encoding2 := mload(ptr) ptr := add(ptr, 0x20) } if gt(cnt, 2) { encoding3 := mload(ptr) ptr := add(ptr, 0x20) } } if (encoding1 == 0) { revert ErrorInvalidEncodings(); } else if (encoding2 == 0) { prices[i] = _readSpotPrice(encoding1); } else if (encoding3 == 0) { prices[i] = _readSpotPrice(encoding1, encoding2); } else { prices[i] = _readSpotPrice(encoding1, encoding2, encoding3); } } } /// @dev Internal function to calculate spot price of single pool. /// @param encoding The encoding for the pool. /// @return price The spot price of the source, multiplied by 1e18. function _readSpotPrice(uint256 encoding) private view returns (uint256 price) { price = ISpotPriceOracle(spotPriceOracle).getSpotPrice(encoding); } /// @dev Internal function to calculate spot price of two pools. /// @param encoding1 The encoding for the first pool. /// @param encoding2 The encoding for the second pool. /// @return price The spot price of the source, multiplied by 1e18. function _readSpotPrice(uint256 encoding1, uint256 encoding2) private view returns (uint256 price) { unchecked { price = (_readSpotPrice(encoding1) * _readSpotPrice(encoding2)) / PRECISION; } } /// @dev Internal function to calculate spot price of three pools. /// @param encoding1 The encoding for the first pool. /// @param encoding2 The encoding for the second pool. /// @param encoding3 The encoding for the third pool. /// @return price The spot price of the source, multiplied by 1e18. function _readSpotPrice( uint256 encoding1, uint256 encoding2, uint256 encoding3 ) private view returns (uint256 price) { unchecked { price = (_readSpotPrice(encoding1, encoding2) * _readSpotPrice(encoding3)) / PRECISION; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0 || ^0.8.0; interface IFxPriceOracleV2 { /********** * Events * **********/ /// @notice Emitted when the value of maximum price deviation is updated. /// @param oldValue The value of the previous maximum price deviation. /// @param newValue The value of the current maximum price deviation. event UpdateMaxPriceDeviation(uint256 oldValue, uint256 newValue); /************************* * Public View Functions * *************************/ /// @notice Return the oracle price with 18 decimal places. /// @return isValid Whether the oracle price is valid -- the difference between `minPrice` and `maxPrice` is reasonable. /// @return twap The time-weighted average price, multiplied by 1e18. It should be the anchor price for this asset, which is hard to manipulate. /// @return minPrice The minimum oracle price among all available price sources (including twap), multiplied by 1e18. /// @return maxPrice The maximum oracle price among all available price sources (including twap), multiplied by 1e18. function getPrice() external view returns ( bool isValid, uint256 twap, uint256 minPrice, uint256 maxPrice ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0 || ^0.8.0; interface IFxRateProvider { /// @notice Return the exchange rate from wrapped token to underlying rate, /// multiplied by 1e18. function getRate() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0 || ^0.8.0; interface IBalancerPool { /// @notice Returns this Pool's ID, used when interacting with the Vault (to e.g. join the Pool or swap with it). function getPoolId() external view returns (bytes32); /// @notice Returns the scaling factors of each of the Pool's tokens. This is an implementation detail that is typically /// not relevant for outside parties, but which might be useful for some types of Pools. function getScalingFactors() external view returns (uint256[] memory); /// @notice Returns the cached value for token's rate. Reverts if the token doesn't belong to the pool or has no rate /// provider. function getTokenRateCache(address token) external view returns ( uint256 rate, uint256 oldRate, uint256 duration, uint256 expires ); /************************** * WeightedPool Functions * **************************/ /// @notice Returns all normalized weights, in the same order as the Pool's tokens. function getNormalizedWeights() external view returns (uint256[] memory); /********************************** * ComposableStablePool Functions * **********************************/ function getAmplificationParameter() external view returns ( uint256 value, bool isUpdating, uint256 precision ); /// @notice Returns the effective BPT supply. /// /// In other pools, this would be the same as `totalSupply`, but there are two key differences here: /// - this pool pre-mints BPT and holds it in the Vault as a token, and as such we need to subtract the Vault's /// balance to get the total "circulating supply". This is called the 'virtualSupply'. /// - the Pool owes debt to the Protocol in the form of unminted BPT, which will be minted immediately before the /// next join or exit. We need to take these into account since, even if they don't yet exist, they will /// effectively be included in any Pool operation that involves BPT. /// /// In the vast majority of cases, this function should be used instead of `totalSupply()`. function getActualSupply() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0 || ^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 latestAnswer() 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 pragma solidity ^0.7.0 || ^0.8.0; interface ISpotPriceOracle { /// @notice Return spot price with 18 decimal places. /// /// @dev encoding for single route /// | 8 bits | 160 bits | 88 bits | /// | pool_type | pool | customized | /// assume all base and quote token has no more than 18 decimals. /// /// + pool_type = 0: UniswapV2 /// customized = | 1 bit | 8 bits | 8 bits | ... | /// | base_index | base_scale | quote_scale | ... | /// + pool_type = 1: UniswapV3 /// customized = | 1 bit | 8 bits | 8 bits | ... | /// | base_index | base_scale | quote_scale | ... | /// + pool_type = 2: Balancer V2 Weighted /// customized = | 3 bit | 3 bit | 8 bits | 8 bits | ... | /// | base_index | quote_index | base_scale | quote_scale | ... | /// + pool_type = 3: Balancer V2 Stable /// customized = | 3 bits | 3 bits | ... | /// | base_index | quote_index | ... | /// + pool_type = 4: Curve Plain /// customized = | 3 bits | 3 bits | 3 bits | 1 bits | 8 bits | ... | 8 bits | ... | /// | tokens | base_index | quote_index | has_amm_precise | scale[0] | ... | scale[n] | ... | /// + pool_type = 5: Curve Plain with oracle /// customized = | 1 bit | 1 bit |... | /// | base_index | use_cache | ... | /// + pool_type = 6: Curve Plain NG /// customized = | 3 bits | 3 bits | 1 bit | ... | /// | base_index | quote_index | use_cache | ... | /// + pool_type = 7: Curve Crypto /// customized = | 1 bit | ... | /// | base_index | ... | /// + pool_type = 8: Curve TriCrypto /// customized = | 2 bits | 2 bits | ... | /// | base_index | quote_index | ... | /// + pool_type = 9: ERC4626 /// customized = | 1 bit | ... | /// | base_is_underlying | ... | /// + pool_type = 10: ETHLSD, wstETH, weETH, ezETH /// customized = | 1 bit | ... | /// | base_is_ETH | ... | /// + pool_type = 11: BalancerV2CachedRate /// customized = | 3 bits | ... | /// | base_index | ... | /// /// @param encoding The encoding of the price source. /// @return spotPrice The spot price with 18 decimal places. function getSpotPrice(uint256 encoding) external view returns (uint256 spotPrice); }
// SPDX-License-Identifier: MIT pragma solidity ^0.7.0 || ^0.8.0; interface ITwapOracle { /// @notice Return TWAP with 18 decimal places in the epoch ending at the specified timestamp. /// Zero is returned if TWAP in the epoch is not available. /// @param timestamp End Timestamp in seconds of the epoch /// @return TWAP (18 decimal places) in the epoch, or zero if not available function getTwap(uint256 timestamp) external view returns (uint256); /// @notice Return the latest price with 18 decimal places. function getLatest() external view returns (uint256); }
{ "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "shanghai", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_spotPriceOracle","type":"address"},{"internalType":"bytes32","name":"_Chainlink_ETH_USD_Spot","type":"bytes32"},{"internalType":"address","name":"_Chainlink_ETH_USD_Twap","type":"address"},{"internalType":"address","name":"_Balancer_ezETH_Pool","type":"address"},{"internalType":"address","name":"_RedStone_ezETH_ETH_Twap","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ErrorInvalidEncodings","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newValue","type":"uint256"}],"name":"UpdateMaxPriceDeviation","type":"event"},{"inputs":[],"name":"Balancer_ezETH_Pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Chainlink_ETH_USD_Spot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"Chainlink_ETH_USD_Twap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RedStone_ezETH_ETH_Twap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getETHUSDSpotPrice","outputs":[{"internalType":"uint256","name":"chainlinkPrice","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getETHUSDSpotPrices","outputs":[{"internalType":"uint256[]","name":"prices","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getETHUSDTwap","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLSDETHSpotPrices","outputs":[{"internalType":"uint256[]","name":"prices","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLSDUSDSpotPrices","outputs":[{"internalType":"uint256[]","name":"prices","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLSDUSDTwap","outputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrice","outputs":[{"internalType":"bool","name":"isValid","type":"bool"},{"internalType":"uint256","name":"twap","type":"uint256"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPriceDeviation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxPriceDeviation","type":"uint256"}],"name":"updateMaxPriceDeviation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodings","type":"bytes"},{"internalType":"uint256","name":"spotType","type":"uint256"}],"name":"updateOnchainSpotEncodings","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
61012060405234801562000011575f80fd5b50604051620013ac380380620013ac833981016040819052620000349162000159565b83838662000042336200008b565b6001600160a01b0390811660805260a0839052811660c0526200006c662386f26fc10000620000a9565b50506001600160a01b0391821660e052166101005250620001bc915050565b600180546001600160a01b0319169055620000a681620000ee565b50565b600580549082905560408051828152602081018490527f23df930eba8ee7044ae7ac6a1957ef1e8e314bdcebc6347bc92decdbff21b717910160405180910390a15050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b038116811462000154575f80fd5b919050565b5f805f805f60a086880312156200016e575f80fd5b62000179866200013d565b94506020860151935062000190604087016200013d565b9250620001a0606087016200013d565b9150620001b0608087016200013d565b90509295509295909350565b60805160a05160c05160e05161010051611196620002165f395f818161012501526107b401525f8181610191015261085e01525f81816101f30152610aea01525f818161021a01526108ee01525f610b7301526111965ff3fe608060405234801561000f575f80fd5b506004361061011c575f3560e01c806384de4087116100a9578063c6bd4b251161006e578063c6bd4b25146102a2578063e30c3978146102aa578063f2fde38b146102bb578063f65932fe146102ce578063fe6b400d146102d6575f80fd5b806384de4087146102155780638da5cb5b1461023c5780639224a3351461024c578063975b86621461026f57806398d5fdca14610278575f80fd5b80636b7d4141116100ef5780636b7d4141146101b3578063715018a6146101c857806379ba5097146101d05780637b60b8d5146101d85780638281e85c146101ee575f80fd5b80631ec46c2d146101205780632427546d1461016457806324f1c5c1146101795780632cf9feea1461018c575b5f80fd5b6101477f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b610177610172366004610dbe565b6102de565b005b610177610187366004610e6d565b61035a565b6101477f000000000000000000000000000000000000000000000000000000000000000081565b6101bb61036e565b60405161015b9190610e84565b610177610406565b610177610419565b6101e0610495565b60405190815260200161015b565b6101477f000000000000000000000000000000000000000000000000000000000000000081565b6101e07f000000000000000000000000000000000000000000000000000000000000000081565b5f546001600160a01b0316610147565b61025461049e565b6040805193845260208401929092529082015260600161015b565b6101e060055481565b6102806104b5565b604080519415158552602085019390935291830152606082015260800161015b565b6101e06104ec565b6001546001600160a01b0316610147565b6101776102c9366004610ec7565b6104f5565b6101bb610565565b6101bb610577565b6102e6610589565b5f6102f0836105e2565b9050815f0361032c5760026103058482610f72565b5080515f036103275760405163f23044db60e01b815260040160405180910390fd5b505050565b816001036103465760036103408482610f72565b50505050565b816002036103275760046103408482610f72565b610362610589565b61036b81610735565b50565b60606104016003805461038090610eed565b80601f01602080910402602001604051908101604052809291908181526020018280546103ac90610eed565b80156103f75780601f106103ce576101008083540402835291602001916103f7565b820191905f5260205f20905b8154815290600101906020018083116103da57829003601f168201915b50505050506105e2565b905090565b61040e610589565b6104175f61077a565b565b60015433906001600160a01b0316811461048c5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b61036b8161077a565b5f610401610793565b5f805f6104a96108e6565b91959094509092509050565b5f805f806104c1610793565b92506104cc836109cd565b6005548202828203670de0b6b3a764000002109694955090939092509050565b5f610401610ad3565b6104fd610589565b600180546001600160a01b0383166001600160a01b0319909116811790915561052d5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b60606104016004805461038090610eed565b60606104016002805461038090610eed565b5f546001600160a01b031633146104175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610483565b602081015160609060218301905f1a8067ffffffffffffffff81111561060a5761060a610daa565b604051908082528060200260200182016040528015610633578160200160208202803683370190505b5092505f5b8181101561072d575f805f85515f1a6001870196505f81111561066057865193506020870196505b600181111561067457865192506020870196505b600281111561068857865191506020870196505b50825f036106a95760405163f23044db60e01b815260040160405180910390fd5b815f036106dc576106b983610b5b565b8785815181106106cb576106cb61102e565b602002602001018181525050610717565b805f036106ed576106b98383610bea565b6106f8838383610c1c565b87858151811061070a5761070a61102e565b6020026020010181815250505b505050808061072590611056565b915050610638565b505050919050565b600580549082905560408051828152602081018490527f23df930eba8ee7044ae7ac6a1957ef1e8e314bdcebc6347bc92decdbff21b717910160405180910390a15050565b600180546001600160a01b031916905561036b81610c50565b604051639f05715160e01b81524260048201525f9081906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639f05715190602401602060405180830381865afa1580156107f9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061081d919061106e565b90505f610828610ad3565b604051637f1260d160e01b815273bf5495efe5db9ce00f80364c8b423567e58d211060048201529091505f906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690637f1260d190602401608060405180830381865afa1580156108a3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108c79190611085565b505050905080828402816108dd576108dd6110b8565b04935050505090565b5f805f6109127f0000000000000000000000000000000000000000000000000000000000000000610c9f565b92505f6109256002805461038090610eed565b90508391508192505f5b81518110156109c6578282828151811061094b5761094b61102e565b602002602001015111156109765781818151811061096b5761096b61102e565b602002602001015192505b838282815181106109895761098961102e565b602002602001015110156109b4578181815181106109a9576109a961102e565b602002602001015193505b806109be81611056565b91505061092f565b5050909192565b80805f806109d96108e6565b92509250505f6109e761036e565b90505f6109f2610565565b82519091505f195f805b83811015610a42575f868281518110610a1757610a1761102e565b6020026020010151905082811115610a2d578092505b83811015610a39578093505b506001016109fc565b508015610a7a57610a5f89670de0b6b3a7640000848a0204610d85565b9850610a7788670de0b6b3a764000083890204610d9c565b97505b835192505f5b83811015610ac6575f858281518110610a9b57610a9b61102e565b6020026020010151905089811115610ab1578099505b8a811015610abd57809a505b50600101610a80565b5050505050505050915091565b604051639f05715160e01b81524260048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639f05715190602401602060405180830381865afa158015610b37573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610401919061106e565b604051630fda366d60e01b8152600481018290525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630fda366d90602401602060405180830381865afa158015610bc0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610be4919061106e565b92915050565b5f670de0b6b3a7640000610bfd83610b5b565b610c0685610b5b565b0281610c1457610c146110b8565b049392505050565b5f670de0b6b3a7640000610c2f83610b5b565b610c398686610bea565b0281610c4757610c476110b8565b04949350505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f805f808460601c925067ffffffffffffffff8560201c16915063ffffffff851690505f80846001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610d00573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d2491906110ea565b50935050925050828142610d389190611136565b1115610d705760405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b6044820152606401610483565b610d7a8483611149565b979650505050505050565b5f818310610d935781610d95565b825b9392505050565b5f818311610d935781610d95565b634e487b7160e01b5f52604160045260245ffd5b5f8060408385031215610dcf575f80fd5b823567ffffffffffffffff80821115610de6575f80fd5b818501915085601f830112610df9575f80fd5b813581811115610e0b57610e0b610daa565b604051601f8201601f19908116603f01168101908382118183101715610e3357610e33610daa565b81604052828152886020848701011115610e4b575f80fd5b826020860160208301375f602093820184015298969091013596505050505050565b5f60208284031215610e7d575f80fd5b5035919050565b602080825282518282018190525f9190848201906040850190845b81811015610ebb57835183529284019291840191600101610e9f565b50909695505050505050565b5f60208284031215610ed7575f80fd5b81356001600160a01b0381168114610d95575f80fd5b600181811c90821680610f0157607f821691505b602082108103610f1f57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115610327575f81815260208120601f850160051c81016020861015610f4b5750805b601f850160051c820191505b81811015610f6a57828155600101610f57565b505050505050565b815167ffffffffffffffff811115610f8c57610f8c610daa565b610fa081610f9a8454610eed565b84610f25565b602080601f831160018114610fd3575f8415610fbc5750858301515b5f19600386901b1c1916600185901b178555610f6a565b5f85815260208120601f198616915b8281101561100157888601518255948401946001909101908401610fe2565b508582101561101e57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161106757611067611042565b5060010190565b5f6020828403121561107e575f80fd5b5051919050565b5f805f8060808587031215611098575f80fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b5f52601260045260245ffd5b805169ffffffffffffffffffff811681146110e5575f80fd5b919050565b5f805f805f60a086880312156110fe575f80fd5b611107866110cc565b945060208601519350604086015192506060860151915061112a608087016110cc565b90509295509295909350565b81810381811115610be457610be4611042565b8082028115828204841417610be457610be461104256fea26469706673582212204c8e679cd4f7b32889efa307993a306ecc45788ca44eb8fc2fd0988eac97869164736f6c63430008140033000000000000000000000000c2312caf0de62ec9b4adc785c79851cb989c9abc5f4ec3df9cbd43714fe2740f5e3616155c5b841900000002540be40000002a300000000000000000000000002eb56aa6a6e48b142287f723e547c687281580bd000000000000000000000000596192bb6e41802428ac943d2f1476c1af25cc0e000000000000000000000000376669afa692a2c6961813c854c78542a3488f55
Deployed Bytecode
0x608060405234801561000f575f80fd5b506004361061011c575f3560e01c806384de4087116100a9578063c6bd4b251161006e578063c6bd4b25146102a2578063e30c3978146102aa578063f2fde38b146102bb578063f65932fe146102ce578063fe6b400d146102d6575f80fd5b806384de4087146102155780638da5cb5b1461023c5780639224a3351461024c578063975b86621461026f57806398d5fdca14610278575f80fd5b80636b7d4141116100ef5780636b7d4141146101b3578063715018a6146101c857806379ba5097146101d05780637b60b8d5146101d85780638281e85c146101ee575f80fd5b80631ec46c2d146101205780632427546d1461016457806324f1c5c1146101795780632cf9feea1461018c575b5f80fd5b6101477f000000000000000000000000376669afa692a2c6961813c854c78542a3488f5581565b6040516001600160a01b0390911681526020015b60405180910390f35b610177610172366004610dbe565b6102de565b005b610177610187366004610e6d565b61035a565b6101477f000000000000000000000000596192bb6e41802428ac943d2f1476c1af25cc0e81565b6101bb61036e565b60405161015b9190610e84565b610177610406565b610177610419565b6101e0610495565b60405190815260200161015b565b6101477f0000000000000000000000002eb56aa6a6e48b142287f723e547c687281580bd81565b6101e07f5f4ec3df9cbd43714fe2740f5e3616155c5b841900000002540be40000002a3081565b5f546001600160a01b0316610147565b61025461049e565b6040805193845260208401929092529082015260600161015b565b6101e060055481565b6102806104b5565b604080519415158552602085019390935291830152606082015260800161015b565b6101e06104ec565b6001546001600160a01b0316610147565b6101776102c9366004610ec7565b6104f5565b6101bb610565565b6101bb610577565b6102e6610589565b5f6102f0836105e2565b9050815f0361032c5760026103058482610f72565b5080515f036103275760405163f23044db60e01b815260040160405180910390fd5b505050565b816001036103465760036103408482610f72565b50505050565b816002036103275760046103408482610f72565b610362610589565b61036b81610735565b50565b60606104016003805461038090610eed565b80601f01602080910402602001604051908101604052809291908181526020018280546103ac90610eed565b80156103f75780601f106103ce576101008083540402835291602001916103f7565b820191905f5260205f20905b8154815290600101906020018083116103da57829003601f168201915b50505050506105e2565b905090565b61040e610589565b6104175f61077a565b565b60015433906001600160a01b0316811461048c5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b60648201526084015b60405180910390fd5b61036b8161077a565b5f610401610793565b5f805f6104a96108e6565b91959094509092509050565b5f805f806104c1610793565b92506104cc836109cd565b6005548202828203670de0b6b3a764000002109694955090939092509050565b5f610401610ad3565b6104fd610589565b600180546001600160a01b0383166001600160a01b0319909116811790915561052d5f546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b60606104016004805461038090610eed565b60606104016002805461038090610eed565b5f546001600160a01b031633146104175760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610483565b602081015160609060218301905f1a8067ffffffffffffffff81111561060a5761060a610daa565b604051908082528060200260200182016040528015610633578160200160208202803683370190505b5092505f5b8181101561072d575f805f85515f1a6001870196505f81111561066057865193506020870196505b600181111561067457865192506020870196505b600281111561068857865191506020870196505b50825f036106a95760405163f23044db60e01b815260040160405180910390fd5b815f036106dc576106b983610b5b565b8785815181106106cb576106cb61102e565b602002602001018181525050610717565b805f036106ed576106b98383610bea565b6106f8838383610c1c565b87858151811061070a5761070a61102e565b6020026020010181815250505b505050808061072590611056565b915050610638565b505050919050565b600580549082905560408051828152602081018490527f23df930eba8ee7044ae7ac6a1957ef1e8e314bdcebc6347bc92decdbff21b717910160405180910390a15050565b600180546001600160a01b031916905561036b81610c50565b604051639f05715160e01b81524260048201525f9081906001600160a01b037f000000000000000000000000376669afa692a2c6961813c854c78542a3488f551690639f05715190602401602060405180830381865afa1580156107f9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061081d919061106e565b90505f610828610ad3565b604051637f1260d160e01b815273bf5495efe5db9ce00f80364c8b423567e58d211060048201529091505f906001600160a01b037f000000000000000000000000596192bb6e41802428ac943d2f1476c1af25cc0e1690637f1260d190602401608060405180830381865afa1580156108a3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108c79190611085565b505050905080828402816108dd576108dd6110b8565b04935050505090565b5f805f6109127f5f4ec3df9cbd43714fe2740f5e3616155c5b841900000002540be40000002a30610c9f565b92505f6109256002805461038090610eed565b90508391508192505f5b81518110156109c6578282828151811061094b5761094b61102e565b602002602001015111156109765781818151811061096b5761096b61102e565b602002602001015192505b838282815181106109895761098961102e565b602002602001015110156109b4578181815181106109a9576109a961102e565b602002602001015193505b806109be81611056565b91505061092f565b5050909192565b80805f806109d96108e6565b92509250505f6109e761036e565b90505f6109f2610565565b82519091505f195f805b83811015610a42575f868281518110610a1757610a1761102e565b6020026020010151905082811115610a2d578092505b83811015610a39578093505b506001016109fc565b508015610a7a57610a5f89670de0b6b3a7640000848a0204610d85565b9850610a7788670de0b6b3a764000083890204610d9c565b97505b835192505f5b83811015610ac6575f858281518110610a9b57610a9b61102e565b6020026020010151905089811115610ab1578099505b8a811015610abd57809a505b50600101610a80565b5050505050505050915091565b604051639f05715160e01b81524260048201525f907f0000000000000000000000002eb56aa6a6e48b142287f723e547c687281580bd6001600160a01b031690639f05715190602401602060405180830381865afa158015610b37573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610401919061106e565b604051630fda366d60e01b8152600481018290525f907f000000000000000000000000c2312caf0de62ec9b4adc785c79851cb989c9abc6001600160a01b031690630fda366d90602401602060405180830381865afa158015610bc0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610be4919061106e565b92915050565b5f670de0b6b3a7640000610bfd83610b5b565b610c0685610b5b565b0281610c1457610c146110b8565b049392505050565b5f670de0b6b3a7640000610c2f83610b5b565b610c398686610bea565b0281610c4757610c476110b8565b04949350505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f805f808460601c925067ffffffffffffffff8560201c16915063ffffffff851690505f80846001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610d00573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d2491906110ea565b50935050925050828142610d389190611136565b1115610d705760405162461bcd60e51b8152602060048201526007602482015266195e1c1a5c995960ca1b6044820152606401610483565b610d7a8483611149565b979650505050505050565b5f818310610d935781610d95565b825b9392505050565b5f818311610d935781610d95565b634e487b7160e01b5f52604160045260245ffd5b5f8060408385031215610dcf575f80fd5b823567ffffffffffffffff80821115610de6575f80fd5b818501915085601f830112610df9575f80fd5b813581811115610e0b57610e0b610daa565b604051601f8201601f19908116603f01168101908382118183101715610e3357610e33610daa565b81604052828152886020848701011115610e4b575f80fd5b826020860160208301375f602093820184015298969091013596505050505050565b5f60208284031215610e7d575f80fd5b5035919050565b602080825282518282018190525f9190848201906040850190845b81811015610ebb57835183529284019291840191600101610e9f565b50909695505050505050565b5f60208284031215610ed7575f80fd5b81356001600160a01b0381168114610d95575f80fd5b600181811c90821680610f0157607f821691505b602082108103610f1f57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115610327575f81815260208120601f850160051c81016020861015610f4b5750805b601f850160051c820191505b81811015610f6a57828155600101610f57565b505050505050565b815167ffffffffffffffff811115610f8c57610f8c610daa565b610fa081610f9a8454610eed565b84610f25565b602080601f831160018114610fd3575f8415610fbc5750858301515b5f19600386901b1c1916600185901b178555610f6a565b5f85815260208120601f198616915b8281101561100157888601518255948401946001909101908401610fe2565b508582101561101e57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f6001820161106757611067611042565b5060010190565b5f6020828403121561107e575f80fd5b5051919050565b5f805f8060808587031215611098575f80fd5b505082516020840151604085015160609095015191969095509092509050565b634e487b7160e01b5f52601260045260245ffd5b805169ffffffffffffffffffff811681146110e5575f80fd5b919050565b5f805f805f60a086880312156110fe575f80fd5b611107866110cc565b945060208601519350604086015192506060860151915061112a608087016110cc565b90509295509295909350565b81810381811115610be457610be4611042565b8082028115828204841417610be457610be461104256fea26469706673582212204c8e679cd4f7b32889efa307993a306ecc45788ca44eb8fc2fd0988eac97869164736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000c2312caf0de62ec9b4adc785c79851cb989c9abc5f4ec3df9cbd43714fe2740f5e3616155c5b841900000002540be40000002a300000000000000000000000002eb56aa6a6e48b142287f723e547c687281580bd000000000000000000000000596192bb6e41802428ac943d2f1476c1af25cc0e000000000000000000000000376669afa692a2c6961813c854c78542a3488f55
-----Decoded View---------------
Arg [0] : _spotPriceOracle (address): 0xc2312CaF0De62eC9b4ADC785C79851Cb989C9abc
Arg [1] : _Chainlink_ETH_USD_Spot (bytes32): 0x5f4ec3df9cbd43714fe2740f5e3616155c5b841900000002540be40000002a30
Arg [2] : _Chainlink_ETH_USD_Twap (address): 0x2EB56aA6A6E48b142287f723E547c687281580bD
Arg [3] : _Balancer_ezETH_Pool (address): 0x596192bB6e41802428Ac943D2f1476C1Af25CC0E
Arg [4] : _RedStone_ezETH_ETH_Twap (address): 0x376669aFa692A2c6961813C854c78542A3488f55
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000c2312caf0de62ec9b4adc785c79851cb989c9abc
Arg [1] : 5f4ec3df9cbd43714fe2740f5e3616155c5b841900000002540be40000002a30
Arg [2] : 0000000000000000000000002eb56aa6a6e48b142287f723e547c687281580bd
Arg [3] : 000000000000000000000000596192bb6e41802428ac943d2f1476c1af25cc0e
Arg [4] : 000000000000000000000000376669afa692a2c6961813c854c78542a3488f55
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 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.