Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 7 from a total of 7 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Create Ojo PT Fe... | 24518383 | 37 days ago | IN | 0 ETH | 0.00000958 | ||||
| Create Ojo PT Fe... | 24383318 | 56 days ago | IN | 0 ETH | 0.0000321 | ||||
| Create Ojo PT Fe... | 24319050 | 65 days ago | IN | 0 ETH | 0.00002579 | ||||
| Create Ojo PT Fe... | 24313634 | 66 days ago | IN | 0 ETH | 0.00002956 | ||||
| Create Ojo PT Fe... | 24313489 | 66 days ago | IN | 0 ETH | 0.00001769 | ||||
| Create Ojo PT Fe... | 24303958 | 67 days ago | IN | 0 ETH | 0.00001048 | ||||
| Create Ojo PT Fe... | 22063188 | 381 days ago | IN | 0 ETH | 0.00021974 |
Latest 16 internal transactions
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| 0x3d602d80 | 24518383 | 37 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 24383318 | 56 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 24319050 | 65 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 24313634 | 66 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 24313489 | 66 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 24303958 | 67 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23671666 | 156 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23671666 | 156 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 23242974 | 216 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 22845671 | 271 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 22434079 | 329 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 22433963 | 329 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 22426550 | 330 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 22288436 | 349 days ago | Contract Creation | 0 ETH | |||
| 0x3d602d80 | 22063188 | 381 days ago | Contract Creation | 0 ETH | |||
| 0x60808060 | 22063076 | 381 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
OjoPTFeedFactory
Compiler Version
v0.8.22+commit.4fc1097e
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.8.22;
import "@openzeppelin/contracts/proxy/Clones.sol";
import "./OjoPTFeed.sol";
contract OjoPTFeedFactory {
using Clones for address;
address public immutable implementation;
mapping(address => address) public OjoPTFeedAddresses;
event OjoPTFeedCreated(address indexed feed);
constructor() {
implementation = address(new OjoPTFeed());
}
function createOjoPTFeed(address FEED_1, address FEED_2) external returns (address FEED) {
FEED = implementation.clone();
OjoPTFeed(FEED).initialize(FEED_1, FEED_2);
OjoPTFeedAddresses[msg.sender] = FEED;
emit OjoPTFeedCreated(FEED);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.2.0) (proxy/Clones.sol)
pragma solidity ^0.8.20;
import {Create2} from "../utils/Create2.sol";
import {Errors} from "../utils/Errors.sol";
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[ERC-1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*/
library Clones {
error CloneArgumentsTooLong();
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
return clone(implementation, 0);
}
/**
* @dev Same as {xref-Clones-clone-address-}[clone], but with a `value` parameter to send native currency
* to the new contract.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function clone(address implementation, uint256 value) internal returns (address instance) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
assembly ("memory-safe") {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create(value, 0x09, 0x37)
}
if (instance == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple times will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
return cloneDeterministic(implementation, salt, 0);
}
/**
* @dev Same as {xref-Clones-cloneDeterministic-address-bytes32-}[cloneDeterministic], but with
* a `value` parameter to send native currency to the new contract.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function cloneDeterministic(
address implementation,
bytes32 salt,
uint256 value
) internal returns (address instance) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
assembly ("memory-safe") {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create2(value, 0x09, 0x37, salt)
}
if (instance == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
assembly ("memory-safe") {
let ptr := mload(0x40)
mstore(add(ptr, 0x38), deployer)
mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
mstore(add(ptr, 0x14), implementation)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
mstore(add(ptr, 0x58), salt)
mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
predicted := and(keccak256(add(ptr, 0x43), 0x55), 0xffffffffffffffffffffffffffffffffffffffff)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt
) internal view returns (address predicted) {
return predictDeterministicAddress(implementation, salt, address(this));
}
/**
* @dev Deploys and returns the address of a clone that mimics the behavior of `implementation` with custom
* immutable arguments. These are provided through `args` and cannot be changed after deployment. To
* access the arguments within the implementation, use {fetchCloneArgs}.
*
* This function uses the create opcode, which should never revert.
*/
function cloneWithImmutableArgs(address implementation, bytes memory args) internal returns (address instance) {
return cloneWithImmutableArgs(implementation, args, 0);
}
/**
* @dev Same as {xref-Clones-cloneWithImmutableArgs-address-bytes-}[cloneWithImmutableArgs], but with a `value`
* parameter to send native currency to the new contract.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function cloneWithImmutableArgs(
address implementation,
bytes memory args,
uint256 value
) internal returns (address instance) {
if (address(this).balance < value) {
revert Errors.InsufficientBalance(address(this).balance, value);
}
bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
assembly ("memory-safe") {
instance := create(value, add(bytecode, 0x20), mload(bytecode))
}
if (instance == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation` with custom
* immutable arguments. These are provided through `args` and cannot be changed after deployment. To
* access the arguments within the implementation, use {fetchCloneArgs}.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy the clone. Using the same
* `implementation`, `args` and `salt` multiple times will revert, since the clones cannot be deployed twice
* at the same address.
*/
function cloneDeterministicWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt
) internal returns (address instance) {
return cloneDeterministicWithImmutableArgs(implementation, args, salt, 0);
}
/**
* @dev Same as {xref-Clones-cloneDeterministicWithImmutableArgs-address-bytes-bytes32-}[cloneDeterministicWithImmutableArgs],
* but with a `value` parameter to send native currency to the new contract.
*
* NOTE: Using a non-zero value at creation will require the contract using this function (e.g. a factory)
* to always have enough balance for new deployments. Consider exposing this function under a payable method.
*/
function cloneDeterministicWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt,
uint256 value
) internal returns (address instance) {
bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
return Create2.deploy(value, salt, bytecode);
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}.
*/
function predictDeterministicAddressWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
bytes memory bytecode = _cloneCodeWithImmutableArgs(implementation, args);
return Create2.computeAddress(salt, keccak256(bytecode), deployer);
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministicWithImmutableArgs}.
*/
function predictDeterministicAddressWithImmutableArgs(
address implementation,
bytes memory args,
bytes32 salt
) internal view returns (address predicted) {
return predictDeterministicAddressWithImmutableArgs(implementation, args, salt, address(this));
}
/**
* @dev Get the immutable args attached to a clone.
*
* - If `instance` is a clone that was deployed using `clone` or `cloneDeterministic`, this
* function will return an empty array.
* - If `instance` is a clone that was deployed using `cloneWithImmutableArgs` or
* `cloneDeterministicWithImmutableArgs`, this function will return the args array used at
* creation.
* - If `instance` is NOT a clone deployed using this library, the behavior is undefined. This
* function should only be used to check addresses that are known to be clones.
*/
function fetchCloneArgs(address instance) internal view returns (bytes memory) {
bytes memory result = new bytes(instance.code.length - 45); // revert if length is too short
assembly ("memory-safe") {
extcodecopy(instance, add(result, 32), 45, mload(result))
}
return result;
}
/**
* @dev Helper that prepares the initcode of the proxy with immutable args.
*
* An assembly variant of this function requires copying the `args` array, which can be efficiently done using
* `mcopy`. Unfortunately, that opcode is not available before cancun. A pure solidity implementation using
* abi.encodePacked is more expensive but also more portable and easier to review.
*
* NOTE: https://eips.ethereum.org/EIPS/eip-170[EIP-170] limits the length of the contract code to 24576 bytes.
* With the proxy code taking 45 bytes, that limits the length of the immutable args to 24531 bytes.
*/
function _cloneCodeWithImmutableArgs(
address implementation,
bytes memory args
) private pure returns (bytes memory) {
if (args.length > 24531) revert CloneArgumentsTooLong();
return
abi.encodePacked(
hex"61",
uint16(args.length + 45),
hex"3d81600a3d39f3363d3d373d3d3d363d73",
implementation,
hex"5af43d82803e903d91602b57fd5bf3",
args
);
}
}// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity ^0.8.22;
import {AggregatorV3Interface} from "./interfaces/AggregatorV2V3Interface.sol";
import {AggregatorV2V3Interface} from "./interfaces/AggregatorV2V3Interface.sol";
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
contract OjoPTFeed is AggregatorV3Interface, Initializable {
uint256 constant DEFAULT_VERSION = 1;
uint256 public constant STALENESS_THRESHOLD = 24 hours;
AggregatorV2V3Interface public FEED_1;
AggregatorV2V3Interface public FEED_2;
string private feedDescription;
error GetRoundDataCanBeOnlyCalledWithLatestRound(uint80 requestedRoundId);
error StaleOracleData(uint256 timestamp, uint256 threshold);
function initialize(address _FEED_1, address _FEED_2) external initializer {
require(_FEED_1 != address(0), "Zero address for FEED_1");
require(_FEED_2 != address(0), "Zero address for FEED_2");
AggregatorV2V3Interface feed1 = AggregatorV2V3Interface(_FEED_1);
AggregatorV2V3Interface feed2 = AggregatorV2V3Interface(_FEED_2);
require(feed1.decimals() == feed2.decimals(), "FEED_1 decimals not equal to FEED_2 decimals");
FEED_1 = feed1;
FEED_2 = feed2;
feedDescription = string(abi.encodePacked("Ojo PT Feed ", feed1.description()));
}
function decimals() external view override returns (uint8) {
return FEED_1.decimals();
}
function description() external view override returns (string memory) {
return feedDescription;
}
function version() external view override returns (uint256) {
return DEFAULT_VERSION;
}
/**
* @notice Returns data for a specific round ID
* @dev Note: This function returns the roundId from whichever oracle provided the minimum price.
* This means roundIds may not be monotonically increasing when switching between oracles,
* which could break protocols that rely on roundId being non-decreasing.
*/
function getRoundData(
uint80 _roundId
)
external
view
override
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
{
(roundId, answer, startedAt, updatedAt, answeredInRound) = latestRoundData();
if (_roundId != roundId) {
revert GetRoundDataCanBeOnlyCalledWithLatestRound(_roundId);
}
return (roundId, answer, startedAt, updatedAt, answeredInRound);
}
/**
* @notice Returns the latest round data
* @dev Note: This function returns the roundId from whichever oracle provided the minimum price.
* This means roundIds may not be monotonically increasing when switching between oracles,
* which could break protocols that rely on roundId being non-decreasing.
*/
function latestRoundData()
public
view
override
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
{
(uint80 roundId1, int256 answer1, uint256 startedAt1, uint256 updatedAt1, uint80 answeredInRound1) =
FEED_1.latestRoundData();
(uint80 roundId2, int256 answer2, uint256 startedAt2, uint256 updatedAt2, uint80 answeredInRound2) =
FEED_2.latestRoundData();
if (updatedAt1 != 0 && block.timestamp - updatedAt1 > STALENESS_THRESHOLD) {
revert StaleOracleData(updatedAt1, STALENESS_THRESHOLD);
}
if (updatedAt2 != 0 && block.timestamp - updatedAt2 > STALENESS_THRESHOLD) {
revert StaleOracleData(updatedAt2, STALENESS_THRESHOLD);
}
if (answer1 <= answer2) {
return (roundId1, answer1, startedAt1, updatedAt1, answeredInRound1);
} else {
return (roundId2, answer2, startedAt2, updatedAt2, answeredInRound2);
}
}
function getActiveOracle() external view returns (address) {
(, int256 answer1,,,) = FEED_1.latestRoundData();
(, int256 answer2,,,) = FEED_2.latestRoundData();
if (answer1 <= answer2) {
return address(FEED_1);
} else {
return address(FEED_2);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Create2.sol)
pragma solidity ^0.8.20;
import {Errors} from "./Errors.sol";
/**
* @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
* `CREATE2` can be used to compute in advance the address where a smart
* contract will be deployed, which allows for interesting new mechanisms known
* as 'counterfactual interactions'.
*
* See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
* information.
*/
library Create2 {
/**
* @dev There's no code to deploy.
*/
error Create2EmptyBytecode();
/**
* @dev Deploys a contract using `CREATE2`. The address where the contract
* will be deployed can be known in advance via {computeAddress}.
*
* The bytecode for a contract can be obtained from Solidity with
* `type(contractName).creationCode`.
*
* Requirements:
*
* - `bytecode` must not be empty.
* - `salt` must have not been used for `bytecode` already.
* - the factory must have a balance of at least `amount`.
* - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
*/
function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) {
if (address(this).balance < amount) {
revert Errors.InsufficientBalance(address(this).balance, amount);
}
if (bytecode.length == 0) {
revert Create2EmptyBytecode();
}
assembly ("memory-safe") {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
// if no address was created, and returndata is not empty, bubble revert
if and(iszero(addr), not(iszero(returndatasize()))) {
let p := mload(0x40)
returndatacopy(p, 0, returndatasize())
revert(p, returndatasize())
}
}
if (addr == address(0)) {
revert Errors.FailedDeployment();
}
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
* `bytecodeHash` or `salt` will result in a new destination address.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
/**
* @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
* `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
*/
function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {
assembly ("memory-safe") {
let ptr := mload(0x40) // Get free memory pointer
// | | ↓ ptr ... ↓ ptr + 0x0B (start) ... ↓ ptr + 0x20 ... ↓ ptr + 0x40 ... |
// |-------------------|---------------------------------------------------------------------------|
// | bytecodeHash | CCCCCCCCCCCCC...CC |
// | salt | BBBBBBBBBBBBB...BB |
// | deployer | 000000...0000AAAAAAAAAAAAAAAAAAA...AA |
// | 0xFF | FF |
// |-------------------|---------------------------------------------------------------------------|
// | memory | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |
// | keccak(start, 85) | ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |
mstore(add(ptr, 0x40), bytecodeHash)
mstore(add(ptr, 0x20), salt)
mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
mstore8(start, 0xff)
addr := and(keccak256(start, 85), 0xffffffffffffffffffffffffffffffffffffffff)
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of common custom errors used in multiple contracts
*
* IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
* It is recommended to avoid relying on the error API for critical functionality.
*
* _Available since v5.1._
*/
library Errors {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error InsufficientBalance(uint256 balance, uint256 needed);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedCall();
/**
* @dev The deployment failed.
*/
error FailedDeployment();
/**
* @dev A necessary precompile is missing.
*/
error MissingPrecompile(address);
}// SPDX-License-Identifier: MIT
pragma solidity >=0.5.0;
interface AggregatorInterface {
function latestAnswer() external view returns (int256);
function latestTimestamp() external view returns (uint256);
function latestRound() external view returns (uint256);
function getAnswer(
uint256 roundId
) external view returns (int256);
function getTimestamp(
uint256 roundId
) external view returns (uint256);
event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);
event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);
}
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);
}
interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface {}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}{
"remappings": [
"forge-std/=lib/forge-std/src/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "shanghai",
"viaIR": true,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"FailedDeployment","type":"error"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"InsufficientBalance","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"feed","type":"address"}],"name":"OjoPTFeedCreated","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"OjoPTFeedAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"FEED_1","type":"address"},{"internalType":"address","name":"FEED_2","type":"address"}],"name":"createOjoPTFeed","outputs":[{"internalType":"address","name":"FEED","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a0806040523461007c57610c838181016001600160401b038111838210176100685782916102f8833903905ff0801561005d576001600160a01b03166080526040516102779081610081823960805181818160bf01526101fc0152f35b6040513d5f823e3d90fd5b634e487b7160e01b5f52604160045260245ffd5b5f80fdfe608060408181526004361015610013575f80fd5b5f915f3560e01c9081635c60da1b146101ea57508063d117eccb1461007c5763d1d698e114610040575f80fd5b34610078576020366003190112610078576020916001600160a01b039082908261006861022b565b1681528085522054169051908152f35b5080fd5b5090346101d557816003193601126101d55761009661022b565b6001600160a01b0390602435828116908190036101d5576e5af43d82803e903d91602b57fd5bf37f0000000000000000000000000000000000000000000000000000000000000000763d602d80600a3d3981f3363d3d373d3d3d363d7300000062ffffff8260881c16175f5260781b1760205282603760095ff0169283156101d957833b156101d557855163485cc95560e01b81529216600483015260248201525f8160448183865af180156101cb57610199575b50807f26b9b4af2e39ec1b98baf623b9b23b57f0385d52216304f5f3def7a55609e51a602094338552848652808520836bffffffffffffffffffffffff60a01b825416179055519380a28152f35b92915067ffffffffffffffff83116101b757918152905f908061014b565b634e487b7160e01b5f52604160045260245ffd5b84513d5f823e3d90fd5b5f80fd5b855163b06ebf3d60e01b8152600490fd5b346101d5575f3660031901126101d5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b600435906001600160a01b03821682036101d55756fea264697066735822122054311f45b79b722553da85d549086dd24243ce99d48dd97175a6739b1c528e0464736f6c634300081600336080806040523461001657610c68908161001b8239f35b5f80fdfe6080604090808252600480361015610015575f80fd5b5f3560e01c918263313ce567146108545750816341299f941461082c578163485cc9551461030457816354fd4d50146102e95781637215b0bf146102cc5781637284e416146101d157816372b14462146101a45781639a6fc8f51461011157508063d84bd024146100ea5763feaf968c1461008e575f80fd5b346100e6575f3660031901126100e6576100e2906100aa610aae565b945169ffffffffffffffffffff94851681526020810193909352604083019190915260608201529116608082015290819060a0820190565b0390f35b5f80fd5b50346100e6575f3660031901126100e6575f5490516001600160a01b039091168152602090f35b9050346100e65760203660031901126100e65780359069ffffffffffffffffffff908183168093036100e657610145610aae565b949192969093958616810361018e575050945169ffffffffffffffffffff938416815260208101949094526040840194909452606083019390935291909116608082015260a090f35b87516322bfd6df60e01b81529182015260249150fd5b82346100e6575f3660031901126100e6576020906101c06109c1565b90516001600160a01b039091168152f35b82346100e6575f3660031901126100e6578051905f916002546101f38161093d565b808352826020958692838301946001906001811690815f146102ad5750600114610250575b5050610226925003836108ee565b61024283519485938185525192838092860152858501906108cd565b601f01601f19168101030190f35b9093915060025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace935f915b81831061029557508894505082010161022688610218565b8554888401850152948501948794509183019161027d565b91505061022694925060ff19168552151560051b820101869288610218565b82346100e6575f3660031901126100e65760209051620151808152f35b82346100e6575f3660031901126100e6576020905160018152f35b82346100e657806003193601126100e6576001600160a01b038235818116939192908490036100e657602480359384168094036100e6577ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a009485549360ff85851c16159267ffffffffffffffff9283871696871580610825575b6001809914908161081b575b159081610812575b506108025767ffffffffffffffff19811688178a55856107e3575b5080156107a157871561075f57855163313ce56760e01b80825260209991908a828781875afa918215610736575f92610740575b5088519081528a818781865afa9081156107365760ff9182915f91610709575b50169116036106b25783915f916bffffffffffffffffffffffff60a01b82818554161784558a5416178955875194858092633942720b60e11b82525afa9283156106a8575f93610620575b5061048d602c875180956b027b53790282a102332b2b2160a51b8c83015261047d8c825192839186860191016108cd565b810103600c8101865201846108ee565b825193841161060f57505081906104a560025461093d565b601f81116105a0575b508690601f8311600114610521575f92610516575b50505f19600383901b1c191690841b176002555b6104dd57005b7fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29368ff000000000000000019815416905551908152a1005b0151905087806104c3565b90869350601f1983169160025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace925f5b8a82821061058a5750508411610572575b505050811b016002556104d7565b01515f1960f88460031b161c19169055878080610564565b8385015186558a97909501949384019301610553565b90915060025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace601f840160051c810191888510610605575b84939291601f89920160051c01915b8281106105f75750506104ae565b5f81558594508891016105e9565b90915081906105da565b604190634e487b7160e01b5f52525ffd5b9092503d805f833e61063281836108ee565b81019088818303126100e6578051908582116100e6570181601f820112156100e657805185811161069657875192610673601f8301601f19168c01856108ee565b8184528a82840101116100e65761068f918a80850191016108cd565b918961044c565b83604186634e487b7160e01b5f52525ffd5b86513d5f823e3d90fd5b865162461bcd60e51b81528085018a9052602c818501527f464545445f3120646563696d616c73206e6f7420657175616c20746f2046454560448201526b445f3220646563696d616c7360a01b6064820152608490fd5b61072991508d803d1061072f575b61072181836108ee565b810190610924565b8e610401565b503d610717565b89513d5f823e3d90fd5b6107589192508b3d8d1161072f5761072181836108ee565b908c6103e1565b855162461bcd60e51b81526020818501526017818401527f5a65726f206164647265737320666f7220464545445f320000000000000000006044820152606490fd5b855162461bcd60e51b81526020818501526017818401527f5a65726f206164647265737320666f7220464545445f310000000000000000006044820152606490fd5b68ffffffffffffffffff191668010000000000000001178955896103ad565b865163f92ee8a960e01b81528490fd5b9050158b610392565b303b15915061038a565b508561037e565b82346100e6575f3660031901126100e65760015490516001600160a01b039091168152602090f35b9150346100e6575f3660031901126100e6575f5463313ce56760e01b8352602091839182906001600160a01b03165afa9081156108c357916020925f926108a1575b5060ff905191168152f35b60ff9192506108bc90843d861161072f5761072181836108ee565b9190610896565b82513d5f823e3d90fd5b5f5b8381106108de5750505f910152565b81810151838201526020016108cf565b90601f8019910116810190811067ffffffffffffffff82111761091057604052565b634e487b7160e01b5f52604160045260245ffd5b908160209103126100e6575160ff811681036100e65790565b90600182811c9216801561096b575b602083101461095757565b634e487b7160e01b5f52602260045260245ffd5b91607f169161094c565b519069ffffffffffffffffffff821682036100e657565b908160a09103126100e6576109a081610975565b916020820151916040810151916109be608060608401519301610975565b90565b5f54604051633fabe5a360e21b8082526001600160a01b0392831692909160a0918282600481885afa918215610a5e575f92610a69575b5060015416926040519081528281600481875afa928315610a5e575f93610a2a575b505013610a25575090565b905090565b610a4a929350803d10610a57575b610a4281836108ee565b81019061098c565b5050509050905f80610a1a565b503d610a38565b6040513d5f823e3d90fd5b610a81919250833d8511610a5757610a4281836108ee565b5050509050905f6109f8565b91908203918211610a9a57565b634e487b7160e01b5f52601160045260245ffd5b60018060a01b03805f541660408051938492633fabe5a360e21b9081855284600460a09889935afa928315610c29575f915f975f975f975f97610bf2575b5081906001541692600485518095819382525afa8015610be8575f80945f945f945f94610bbd575b505089151580610ba8575b610b885783151580610b73575b610b535750848b13610b445750505050509493929190565b99509297509095509350919050565b51635f51811b60e11b815260048101849052620151806024820152604490fd5b5062015180610b828542610a8d565b11610b2c565b51635f51811b60e11b8152600481018a9052620151806024820152604490fd5b5062015180610bb78b42610a8d565b11610b1f565b93509350945050610bda9250803d10610a5757610a4281836108ee565b929491939092915f80610b14565b83513d5f823e3d90fd5b9299509550809750610c149296508093503d8411610a5757610a4281836108ee565b97939992949199989098949998979690610aec565b513d5f823e3d90fdfea26469706673582212207ef3530a3a8bbb281a55c2023c13d4b560902b508907f8832b0218445a9a45dd64736f6c63430008160033
Deployed Bytecode
0x608060408181526004361015610013575f80fd5b5f915f3560e01c9081635c60da1b146101ea57508063d117eccb1461007c5763d1d698e114610040575f80fd5b34610078576020366003190112610078576020916001600160a01b039082908261006861022b565b1681528085522054169051908152f35b5080fd5b5090346101d557816003193601126101d55761009661022b565b6001600160a01b0390602435828116908190036101d5576e5af43d82803e903d91602b57fd5bf37f0000000000000000000000005aab95e3c6f9ba0ccfa0a17c2c7235633c7c6585763d602d80600a3d3981f3363d3d373d3d3d363d7300000062ffffff8260881c16175f5260781b1760205282603760095ff0169283156101d957833b156101d557855163485cc95560e01b81529216600483015260248201525f8160448183865af180156101cb57610199575b50807f26b9b4af2e39ec1b98baf623b9b23b57f0385d52216304f5f3def7a55609e51a602094338552848652808520836bffffffffffffffffffffffff60a01b825416179055519380a28152f35b92915067ffffffffffffffff83116101b757918152905f908061014b565b634e487b7160e01b5f52604160045260245ffd5b84513d5f823e3d90fd5b5f80fd5b855163b06ebf3d60e01b8152600490fd5b346101d5575f3660031901126101d5577f0000000000000000000000005aab95e3c6f9ba0ccfa0a17c2c7235633c7c65856001600160a01b03168152602090f35b600435906001600160a01b03821682036101d55756fea264697066735822122054311f45b79b722553da85d549086dd24243ce99d48dd97175a6739b1c528e0464736f6c63430008160033
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.