Address Contract Partially Verified
Address
0x67283c357053185F0eF0dF2F2a37f8191114Dfb7
Balance
0 ETH
Nonce
1
Code Size
1390 bytes
Creator
0x43A31418...2780 at tx 0x1470f0f5...3a9cbc
Indexed Transactions
0
Contract Bytecode
1390 bytes
0x608060405234801561000f575f80fd5b506004361061007a575f3560e01c80638da5cb5b116100585780638da5cb5b146100ae5780639c52a7f1146100cd578063bf353dbb146100e0578063f2fde38b1461010d575f80fd5b80634abf8e271461007e57806365fae35e14610093578063715018a6146100a6575b5f80fd5b61009161008c36600461041f565b610120565b005b6100916100a1366004610502565b61028a565b6100916102ae565b5f546040516001600160a01b0390911681526020015b60405180910390f35b6100916100db366004610502565b6102c1565b6100ff6100ee366004610502565b60016020525f908152604090205481565b6040519081526020016100c4565b61009161011b366004610502565b6102e2565b335f90815260016020526040812054900361014d576040516282b42960e81b815260040160405180910390fd5b825181811461016f57604051638c38e89d60e01b815260040160405180910390fd5b5f5b818110156102835784818151811061018b5761018b610524565b60200260200101516001600160a01b031663a08edce88585848181106101b3576101b3610524565b905060200201356040518263ffffffff1660e01b81526004016101d891815260200190565b5f604051808303815f87803b1580156101ef575f80fd5b505af1925050508015610200575060015b61027b577f8cc1621726ea8d418994e43b06ac780b61a086a253d7b4537443dbc33ded690d85828151811061023757610237610524565b602002602001015185858481811061025157610251610524565b604080516001600160a01b0390951685526020918202939093013590840152500160405180910390a15b600101610171565b5050505050565b610292610324565b6001600160a01b03165f90815260016020819052604090912055565b6102b6610324565b6102bf5f610350565b565b6102c9610324565b6001600160a01b03165f90815260016020526040812055565b6102ea610324565b6001600160a01b03811661031857604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b61032181610350565b50565b5f546001600160a01b031633146102bf5760405163118cdaa760e01b815233600482015260240161030f565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b5f52604160045260245ffd5b6001600160a01b0381168114610321575f80fd5b80356103d2816103b3565b919050565b5f8083601f8401126103e7575f80fd5b50813567ffffffffffffffff8111156103fe575f80fd5b6020830191508360208260051b8501011115610418575f80fd5b9250929050565b5f805f60408486031215610431575f80fd5b833567ffffffffffffffff80821115610448575f80fd5b818601915086601f83011261045b575f80fd5b813560208282111561046f5761046f61039f565b8160051b604051601f19603f830116810181811086821117156104945761049461039f565b6040529283528481018201928281018b8511156104af575f80fd5b958301955b848710156104d2576104c5876103c7565b81529583019583016104b4565b50975050870135925050808211156104e8575f80fd5b506104f5868287016103d7565b9497909650939450505050565b5f60208284031215610512575f80fd5b813561051d816103b3565b9392505050565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220552c0964a0af22828aba02b3e0c2141fdb7de61965c3e896ed87ee477dfc7f9664736f6c63430008170033
Verified Source Code Partial Match
Compiler: v0.8.23+commit.f704f362
EVM: shanghai
Optimization: Yes (200 runs)
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @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;
}
}
Ownable.sol 100 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "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.
*
* The initial owner is set to the address provided by the deployer. 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;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @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 {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @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 {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_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);
}
}
Upgradeable.sol 10 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.23;
import {Ownable} from "Ownable.sol";
contract Upgradeable is Ownable {
address public implementation;
constructor() Ownable(msg.sender) {}
}
BatchUpdateRate.sol 44 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.23;
import "FungifyPriceFeed.sol";
import "Ownable.sol";
// This is intended to reduce the number of transactions made.
contract BatchUpdateRate is Ownable {
// --- Auth ---
mapping (address => uint) public wards;
function rely(address guy) external onlyOwner { wards[guy] = 1; }
function deny(address guy) external onlyOwner { wards[guy] = 0; }
modifier auth {
if (wards[msg.sender] == 0) {
revert Unauthorized();
}
_;
}
event FailedToUpdate(FungifyPriceFeed feed, int256 answer);
error UnequalParamLengths();
error Unauthorized();
constructor() Ownable(msg.sender) {}
// Sets the price answer to multiple price feeds at once
function batchSetAnswer(FungifyPriceFeed[] memory priceFeeds, int256[] calldata newAnswers) external auth {
uint numFeeds = priceFeeds.length;
if (numFeeds != newAnswers.length) {
revert UnequalParamLengths();
}
// Loops through all the provided feeds and attempts to set their answers
for (uint i = 0; i < numFeeds;) {
try priceFeeds[i].updateRate(newAnswers[i]) {
} catch {
emit FailedToUpdate(priceFeeds[i], newAnswers[i]);
}
unchecked { i++; }
}
}
}
FungifyPriceFeed.sol 184 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.23;
import "Upgradeable.sol";
contract FungifyPriceFeed is Upgradeable {
event RateUpdated(int256 oldRate, int256 newRate, int256 inputRate);
error UnderTimeAndPriceDeviationMinimums();
error OverPriceDeviationMaximum();
error Unauthorized();
error AdditionOverflow();
error SubtractionOverflow();
error LessThanTwoPeriods();
// --- Auth ---
mapping (address => uint256) public wards;
function rely(address guy) external onlyOwner { wards[guy] = 1; }
function deny(address guy) external onlyOwner { wards[guy] = 0; }
modifier auth {
if (wards[msg.sender] == 0) {
revert Unauthorized();
}
_;
}
int256 public constant ONE_IN_BIP = 10000;
uint8 public immutable _decimals;
int256 public latestAnswer;
uint256 public latestUpdateTime;
// Variables for price updating assertions
int256 public minPriceDeviationBip; // Defined in basis points: 1 Bip = .01%
uint256 public stalePriceTime;
int256 public emaPeriods; // averaging periods for EMA calculation
int public maxPriceDeviationBip; // Defined in basis points: 1 Bip = .01%
constructor(uint8 decimals_) {
_decimals = decimals_;
}
function initialize(int256 startingRate_) external {
if (msg.sender != owner()) {
revert Unauthorized();
}
latestAnswer = startingRate_;
latestUpdateTime = block.timestamp;
stalePriceTime = 7200;
minPriceDeviationBip = 200;
maxPriceDeviationBip = 3500;
emaPeriods = 3;
emit RateUpdated(0, startingRate_, startingRate_);
}
function decimals() public view returns (uint8) {
return _decimals;
}
function latestRoundData()
public
view
returns (
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
) {
return (0, latestAnswer, 0, latestUpdateTime, 0);
}
// Verifies if a newRate is within the priceDeviationBip of oldRate
function underMinPriceDeviation(int256 newRate, int256 oldRate) public view returns(bool) {
int256 allowedDeviation = oldRate * minPriceDeviationBip / ONE_IN_BIP;
if (newRate > oldRate + allowedDeviation || newRate < oldRate - allowedDeviation) {
return false;
} else {
return true;
}
}
// Verifies that a newRate is within the maxPriceDeviationBip of oldRate
function overMaxPriceDeviation(int256 newRate, int256 oldRate) public view returns(bool) {
int allowedDeviation = oldRate * maxPriceDeviationBip / ONE_IN_BIP;
if (newRate > oldRate + allowedDeviation || newRate < oldRate - allowedDeviation) {
return true;
} else {
return false;
}
}
function updateRate(int256 newRate_) public auth {
int256 oldEMA = latestAnswer;
if (overMaxPriceDeviation(newRate_, oldEMA)) {
revert OverPriceDeviationMaximum();
}
// Performs Price Update Minimum Deviation Time and Price Checks
if (underMinPriceDeviation(newRate_, oldEMA) && block.timestamp < latestUpdateTime + stalePriceTime) {
revert UnderTimeAndPriceDeviationMinimums();
}
int256 newEMA = updateEMA(oldEMA, newRate_);
latestAnswer = newEMA;
latestUpdateTime = block.timestamp;
emit RateUpdated(oldEMA, newEMA, newRate_);
}
function updateEMA(int256 currentEMA, int256 newValue) internal view returns (int256) {
/*
Multiplier: 2 / (emaPeriods + 1)
EMA: (LastestValue - PreviousEMA) * Multiplier + PreviousEMA
*/
int256 emaPeriods_ = emaPeriods;
int256 newEMA =
sub(
add(
newValue * 2 / (emaPeriods_ + 1),
currentEMA
),
currentEMA * 2 / (emaPeriods_ + 1)
);
return newEMA;
}
function setStalePriceTime(uint _stalePriceTime) external onlyOwner {
stalePriceTime = _stalePriceTime;
}
// Defined in basis points: 1 Bip = .01%
function setMinPriceDeviationBip(int _minPriceDeviationBip) external onlyOwner {
minPriceDeviationBip = _minPriceDeviationBip;
}
// Defined in basis points: 1 Bip = .01%
function setMaxPriceDeviationBip(int _maxPriceDeviationBip) external onlyOwner {
maxPriceDeviationBip = _maxPriceDeviationBip;
}
function setEMAPeriods(int _emaPeriods) external onlyOwner {
if (_emaPeriods < 2) {
revert LessThanTwoPeriods();
}
emaPeriods = _emaPeriods;
}
function adminUpdateRate(int256 newRate_) external onlyOwner {
int256 oldRate = latestAnswer;
latestAnswer = newRate_;
latestUpdateTime = block.timestamp;
emit RateUpdated(oldRate, newRate_, newRate_);
}
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c;
unchecked { c = a + b; }
if (!((b >= 0 && c >= a) || (b < 0 && c < a))) {
revert AdditionOverflow();
}
return c;
}
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c;
unchecked { c = a - b; }
if (!((b >= 0 && c <= a) || (b < 0 && c > a))) {
revert SubtractionOverflow();
}
return c;
}
}
Read Contract
owner 0x8da5cb5b → address
wards 0xbf353dbb → uint256
Write Contract 5 functions
These functions modify contract state and require a wallet transaction to execute.
batchSetAnswer 0x4abf8e27
address[] priceFeeds
int256[] newAnswers
deny 0x9c52a7f1
address guy
rely 0x65fae35e
address guy
renounceOwnership 0x715018a6
No parameters
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
No transactions found for this address