Address Contract Verified
Address
0x15f7744C393CD07bEac9322cE531bd0cB363536b
Balance
0 ETH
Nonce
1
Code Size
3905 bytes
Creator
0xcfaD496f...a781 at tx 0xd42b30c7...abc4ae
Indexed Transactions
0 (1 on-chain, 1.1% indexed)
Contract Bytecode
3905 bytes
0x608060405234801561000f575f80fd5b506004361061012f575f3560e01c8063a0dcdc68116100ad578063d29dba911161007d578063ebbc496511610063578063ebbc49651461030e578063ebdac45814610316578063feaf968c1461033d575f80fd5b8063d29dba91146102db578063e30c3978146102ee575f80fd5b8063a0dcdc6814610279578063acdb31f61461028c578063c42069ec1461029f578063d116c081146102b4575f80fd5b8063620518d8116101025780638a0531a6116100e85780638a0531a6146101cf5780638da5cb5b1461020d578063a06a720714610252575f80fd5b8063620518d8146101b15780637284e416146101ba575f80fd5b80630d73ed7b146101335780631af214a81461015b578063313ce5671461019457806350d25bcd1461019b575b5f80fd5b610146610141366004610aa1565b61037c565b60405190151581526020015b60405180910390f35b6101827f000000000000000000000000000000000000000000000000000000000000000881565b60405160ff9091168152602001610152565b6012610182565b6101a36104ee565b604051908152602001610152565b6101a360035481565b6101c2610503565b6040516101529190610acf565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161515610146565b60015461022d9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610152565b6101827f000000000000000000000000000000000000000000000000000000000000000081565b6101a3610287366004610b38565b61058e565b61014661029a366004610b60565b6105f5565b6102b26102ad366004610b80565b610642565b005b61022d7f000000000000000000000000471a6299c027bd81ed4d66069dc510bd0569f4f881565b6102b26102e9366004610ba2565b61070f565b60025461022d9073ffffffffffffffffffffffffffffffffffffffff1681565b6102b2610795565b61022d7f000000000000000000000000000000000000000000000000000000000000000081565b610345610862565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a001610152565b5f808273ffffffffffffffffffffffffffffffffffffffff1663245a7bfc6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103eb9190610bb9565b90505f8173ffffffffffffffffffffffffffffffffffffffff166370da2f676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610437573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061045b9190610bd4565b90505f8273ffffffffffffffffffffffffffffffffffffffff166322adbc786040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104a7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104cb9190610bd4565b9050858260170b1315806104e25750858160170b12155b93505050505b92915050565b5f806104f8610862565b509195945050505050565b5f805461050f90610bf4565b80601f016020809104026020016040519081016040528092919081815260200182805461053b90610bf4565b80156105865780601f1061055d57610100808354040283529160200191610586565b820191905f5260205f20905b81548152906001019060200180831161056957829003601f168201915b505050505081565b5f60128260ff1611156105c2576105a6601283610c72565b6105b190600a610da9565b6105bb9084610db7565b90506104e8565b60128260ff1610156105ee576105d9826012610c72565b6105e490600a610da9565b6105bb9084610e43565b5090919050565b5f8042600354846106069190610e8e565b109050808061063a575061063a847f000000000000000000000000471a6299c027bd81ed4d66069dc510bd0569f4f861037c565b949350505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4f6e6c79206f776e65720000000000000000000000000000000000000000000060448201526064015b60405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610790576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f4f6e6c79206f776e65720000000000000000000000000000000000000000000060448201526064016106bf565b600355565b60025473ffffffffffffffffffffffffffffffffffffffff163314610816576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f4f6e6c792070656e64696e67206f776e6572000000000000000000000000000060448201526064016106bf565b60028054600180547fffffffffffffffffffffffff000000000000000000000000000000000000000090811673ffffffffffffffffffffffffffffffffffffffff841617909155169055565b5f805f805f7f000000000000000000000000471a6299c027bd81ed4d66069dc510bd0569f4f873ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156108d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108f49190610ebf565b93985091965094509250905061090a84836105f5565b15610a495773ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001615610a15577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156109b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d89190610ebf565b939850919650945092509050610a0e847f000000000000000000000000000000000000000000000000000000000000000061058e565b9350610a76565b610a3f847f000000000000000000000000000000000000000000000000000000000000000861058e565b93505f9150610a76565b610a73847f000000000000000000000000000000000000000000000000000000000000000861058e565b93505b9091929394565b73ffffffffffffffffffffffffffffffffffffffff81168114610a9e575f80fd5b50565b5f8060408385031215610ab2575f80fd5b823591506020830135610ac481610a7d565b809150509250929050565b5f6020808352835180828501525f5b81811015610afa57858101830151858201604001528201610ade565b505f6040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b5f8060408385031215610b49575f80fd5b82359150602083013560ff81168114610ac4575f80fd5b5f8060408385031215610b71575f80fd5b50508035926020909101359150565b5f60208284031215610b90575f80fd5b8135610b9b81610a7d565b9392505050565b5f60208284031215610bb2575f80fd5b5035919050565b5f60208284031215610bc9575f80fd5b8151610b9b81610a7d565b5f60208284031215610be4575f80fd5b81518060170b8114610b9b575f80fd5b600181811c90821680610c0857607f821691505b602082108103610c3f577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b60ff82811682821603908111156104e8576104e8610c45565b600181815b80851115610ce457817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610cca57610cca610c45565b80851615610cd757918102915b93841c9390800290610c90565b509250929050565b5f82610cfa575060016104e8565b81610d0657505f6104e8565b8160018114610d1c5760028114610d2657610d42565b60019150506104e8565b60ff841115610d3757610d37610c45565b50506001821b6104e8565b5060208310610133831016604e8410600b8410161715610d65575081810a6104e8565b610d6f8383610c8b565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610da157610da1610c45565b029392505050565b5f610b9b60ff841683610cec565b5f82610dea577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83147f800000000000000000000000000000000000000000000000000000000000000083141615610e3e57610e3e610c45565b500590565b8082025f82127f800000000000000000000000000000000000000000000000000000000000000084141615610e7a57610e7a610c45565b81810583148215176104e8576104e8610c45565b808201808211156104e8576104e8610c45565b805169ffffffffffffffffffff81168114610eba575f80fd5b919050565b5f805f805f60a08688031215610ed3575f80fd5b610edc86610ea1565b9450602086015193506040860151925060608601519150610eff60808701610ea1565b9050929550929590935056fea26469706673582212203cca3589daf875bbedf4f9e6eb300755a90bc45cecaaff967f518f42b4f4525e64736f6c63430008140033
Verified Source Code Full Match
Compiler: v0.8.20+commit.a1b79de6
EVM: shanghai
Optimization: Yes (10000 runs)
ChainlinkBasePriceFeed.sol 162 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "src/interfaces/IChainlinkFeed.sol";
interface IAggregator {
function maxAnswer() external view returns (int192);
function minAnswer() external view returns (int192);
}
// Standard feed component for FiRM price feeds
/// @dev Always return the feed price in 18 decimals
contract ChainlinkBasePriceFeed {
IChainlinkFeed public immutable assetToUsd;
IChainlinkFeed public immutable assetToUsdFallback;
uint8 public immutable assetToUsdDecimals;
uint8 public immutable assetToUsdFallbackDecimals;
string public description;
address public owner;
address public pendingOwner;
uint256 public assetToUsdHeartbeat;
modifier onlyOwner() {
require(msg.sender == owner, "Only owner");
_;
}
modifier onlyPendingOwner() {
require(msg.sender == pendingOwner, "Only pending owner");
_;
}
constructor(
address _owner,
address _assetToUsd,
address _assetToUsdFallback,
uint256 _assetToUsdHeartbeat
) {
owner = _owner;
assetToUsd = IChainlinkFeed(_assetToUsd);
assetToUsdFallback = IChainlinkFeed(_assetToUsdFallback);
assetToUsdHeartbeat = _assetToUsdHeartbeat;
assetToUsdDecimals = IChainlinkFeed(_assetToUsd).decimals();
uint8 fallbackDecimals = 0;
if (address(assetToUsdFallback) != address(0)) {
fallbackDecimals = assetToUsdFallback.decimals();
}
assetToUsdFallbackDecimals = fallbackDecimals;
description = assetToUsd.description();
}
/**
* @notice Retrieves the latest round data for the asset token price feed
* @return roundId The round ID of the Chainlink price feed for the feed with the lowest updatedAt feed
* @return usdPrice The latest asset price in USD with 18 decimals
* @return startedAt The timestamp when the latest round of Chainlink price feed started of the lowest last updatedAt feed
* @return updatedAt The lowest timestamp when either of the latest round of Chainlink price feed was updated
* @return answeredInRound The round ID in which the answer was computed of the lowest updatedAt feed
*/
function latestRoundData()
public
view
returns (
uint80 roundId,
int256 usdPrice,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
)
{
(roundId, usdPrice, startedAt, updatedAt, answeredInRound) = assetToUsd
.latestRoundData();
if (isPriceStale(usdPrice, updatedAt)) {
if (hasFallback()) {
(
roundId,
usdPrice,
startedAt,
updatedAt,
answeredInRound
) = assetToUsdFallback.latestRoundData();
usdPrice = normalizePrice(usdPrice, assetToUsdFallbackDecimals);
} else {
usdPrice = normalizePrice(usdPrice, assetToUsdDecimals);
updatedAt = 0;
}
} else {
usdPrice = normalizePrice(usdPrice, assetToUsdDecimals);
}
}
/**
* @notice Returns the latest price only
* @dev Unlike chainlink oracles, the latestAnswer will always be the same as in the latestRoundData
* @return int256 Returns the last finalized price of the chainlink oracle
*/
function latestAnswer() external view returns (int256) {
(, int256 latestPrice, , , ) = latestRoundData();
return latestPrice;
}
/**
* @notice Checks if a given price is out of the boundaries defined in the Chainlink aggregator.
* @param price The price to be checked.
* @param feed The Chainlink feed to retrieve the boundary information from.
* @return bool Returns `true` if the price is out of bounds, otherwise `false`.
*/
function isPriceOutOfBounds(
int price,
IChainlinkFeed feed
) public view returns (bool) {
IAggregator aggregator = IAggregator(feed.aggregator());
int192 max = aggregator.maxAnswer();
int192 min = aggregator.minAnswer();
return (max <= price || min >= price);
}
function isPriceStale(
int256 price,
uint256 updatedAt
) public view returns (bool) {
bool stalePrice = updatedAt + assetToUsdHeartbeat < block.timestamp;
return stalePrice || isPriceOutOfBounds(price, assetToUsd);
}
function hasFallback() public view returns (bool) {
return address(assetToUsdFallback) != address(0);
}
function setHeartbeat(uint256 newHeartbeat) public onlyOwner {
assetToUsdHeartbeat = newHeartbeat;
}
function setPendingOwner(address newPendingOwner) public onlyOwner {
pendingOwner = newPendingOwner;
}
function acceptOwner() public onlyPendingOwner {
owner = pendingOwner;
pendingOwner = address(0);
}
function decimals() public pure returns (uint8) {
return 18;
}
function normalizePrice(
int256 price,
uint8 feedDecimals
) public pure returns (int256) {
if (feedDecimals > 18) {
return price / int(10 ** (feedDecimals - 18));
} else if (feedDecimals < 18) {
return price * int(10 ** (18 - feedDecimals));
}
return price;
}
}
IChainlinkFeed.sol 30 lines
pragma solidity ^0.8.13;
interface IChainlinkFeed {
function aggregator() external view returns (address aggregator);
function decimals() external view returns (uint8 decimals);
function latestRoundData()
external
view
returns (
uint80 roundId,
int256 crvUsdPrice,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
);
function latestAnswer() external view returns (int256 price);
function description() external view returns (string memory description);
}
interface IChainlinkBasePriceFeed is IChainlinkFeed {
function assetToUsd() external view returns (IChainlinkFeed);
function assetToUsdFallback() external view returns (IChainlinkFeed);
function assetToUsdHeartbeat() external view returns (uint256 heartbeat);
}
Read Contract
assetToUsd 0xd116c081 → address
assetToUsdDecimals 0x1af214a8 → uint8
assetToUsdFallback 0xebdac458 → address
assetToUsdFallbackDecimals 0xa06a7207 → uint8
assetToUsdHeartbeat 0x620518d8 → uint256
decimals 0x313ce567 → uint8
description 0x7284e416 → string
hasFallback 0x8a0531a6 → bool
isPriceOutOfBounds 0x0d73ed7b → bool
isPriceStale 0xacdb31f6 → bool
latestAnswer 0x50d25bcd → int256
latestRoundData 0xfeaf968c → uint80, int256, uint256, uint256, uint80
normalizePrice 0xa0dcdc68 → int256
owner 0x8da5cb5b → address
pendingOwner 0xe30c3978 → address
Write Contract 3 functions
These functions modify contract state and require a wallet transaction to execute.
acceptOwner 0xebbc4965
No parameters
setHeartbeat 0xd29dba91
uint256 newHeartbeat
setPendingOwner 0xc42069ec
address newPendingOwner
Recent Transactions
This address has 1 on-chain transactions, but only 1.1% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →