Description:
Smart contract deployed on Ethereum with Factory, Oracle features.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"src/v0.8/keystone/OCR3Capability.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol";
import {OCR2Abstract} from "./ocr/OCR2Abstract.sol";
/// @notice OCR2Base provides config management compatible with OCR3
contract OCR3Capability is OwnerIsCreator, OCR2Abstract {
error InvalidConfig(string message);
error ReportingUnsupported();
string public constant override typeAndVersion = "OCR3Capability 1.0.0";
// incremented each time a new config is posted. This count is incorporated
// into the config digest, to prevent replay attacks.
uint32 internal s_configCount;
// makes it easier for offchain systems to extract config from logs.
uint32 internal s_latestConfigBlockNumber;
// Storing these fields used on the hot path in a ConfigInfo variable reduces the
// retrieval of all of them to a single SLOAD. If any further fields are
// added, make sure that storage of the struct still takes at most 32 bytes.
struct ConfigInfo {
bytes32 latestConfigDigest;
uint8 f; // TODO: could be optimized by squeezing into one slot
uint8 n;
}
ConfigInfo internal s_configInfo;
// Reverts transaction if config args are invalid
modifier checkConfigValid(uint256 numSigners, uint256 numTransmitters, uint256 f) {
if (numSigners > MAX_NUM_ORACLES) revert InvalidConfig("too many signers");
if (f == 0) revert InvalidConfig("f must be positive");
if (numSigners != numTransmitters) revert InvalidConfig("oracle addresses out of registration");
if (numSigners <= 3 * f) revert InvalidConfig("faulty-oracle f too high");
_;
}
/// @notice sets offchain reporting protocol configuration incl. participating oracles
/// @param _signers addresses with which oracles sign the reports
/// @param _transmitters addresses oracles use to transmit the reports
/// @param _f number of faulty oracles the system can tolerate
/// @param _onchainConfig encoded on-chain contract configuration
/// @param _offchainConfigVersion version number for offchainEncoding schema
/// @param _offchainConfig encoded off-chain oracle configuration
/// @dev signer = [ 1 byte type | 2 byte len | n byte value ]...
function setConfig(
bytes[] calldata _signers,
address[] calldata _transmitters,
uint8 _f,
bytes memory _onchainConfig,
uint64 _offchainConfigVersion,
bytes memory _offchainConfig
) external override checkConfigValid(_signers.length, _transmitters.length, _f) onlyOwner {
// Bounded by MAX_NUM_ORACLES in OCR2Abstract.sol
for (uint256 i = 0; i < _signers.length; ++i) {
if (_transmitters[i] == address(0)) revert InvalidConfig("transmitter must not be empty");
// add new signers
bytes calldata publicKeys = _signers[i];
uint256 offset = 0;
uint256 publicKeysLength = uint16(publicKeys.length);
// scan through public keys to validate encoded format
while (offset < publicKeysLength) {
if (offset + 3 > publicKeysLength) revert InvalidConfig("invalid signer pubKey encoding");
uint256 keyLen = uint256(uint8(publicKeys[offset + 1])) + (uint256(uint8(publicKeys[offset + 2])) << 8);
if (offset + 3 + keyLen > publicKeysLength) revert InvalidConfig("invalid signer pubKey encoding");
offset += 3 + keyLen;
}
}
s_configInfo.f = _f;
uint32 previousConfigBlockNumber = s_latestConfigBlockNumber;
s_latestConfigBlockNumber = uint32(block.number);
s_configCount += 1;
{
s_configInfo.latestConfigDigest = _configDigestFromConfigData(
block.chainid,
address(this),
s_configCount,
_signers,
_transmitters,
_f,
_onchainConfig,
_offchainConfigVersion,
_offchainConfig
);
}
s_configInfo.n = uint8(_signers.length);
emit ConfigSet(
previousConfigBlockNumber,
s_configInfo.latestConfigDigest,
s_configCount,
_signers,
_transmitters,
_f,
_onchainConfig,
_offchainConfigVersion,
_offchainConfig
);
}
function _configDigestFromConfigData(
uint256 _chainId,
address _contractAddress,
uint64 _configCount,
bytes[] calldata _signers,
address[] calldata _transmitters,
uint8 _f,
bytes memory _onchainConfig,
uint64 _encodedConfigVersion,
bytes memory _encodedConfig
) internal pure returns (bytes32) {
uint256 h = uint256(
keccak256(
abi.encode(
_chainId,
_contractAddress,
_configCount,
_signers,
_transmitters,
_f,
_onchainConfig,
_encodedConfigVersion,
_encodedConfig
)
)
);
uint256 prefixMask = type(uint256).max << (256 - 16); // 0xFFFF00..00
uint256 prefix = 0x000e << (256 - 16); // 0x000e00..00
return bytes32((prefix & prefixMask) | (h & ~prefixMask));
}
/// @notice information about current offchain reporting protocol configuration
/// @return configCount ordinal number of current config, out of all configs applied to this contract so far
/// @return blockNumber block at which this config was set
/// @return configDigest domain-separation tag for current config (see __configDigestFromConfigData)
function latestConfigDetails()
external
view
override
returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest)
{
return (s_configCount, s_latestConfigBlockNumber, s_configInfo.latestConfigDigest);
}
function transmit(
// NOTE: If these parameters are changed, expectedMsgDataLength and/or
// TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly
bytes32[3] calldata /* reportContext */,
bytes calldata /* report */,
bytes32[] calldata /* rs */,
bytes32[] calldata /* ss */,
bytes32 /* rawVs */ // signatures
) external pure override {
revert ReportingUnsupported();
}
/// @inheritdoc OCR2Abstract
function latestConfigDigestAndEpoch()
external
view
virtual
override
returns (bool scanLogs, bytes32 configDigest, uint32 epoch)
{
return (true, bytes32(0), uint32(0));
}
}
"
},
"src/v0.8/shared/access/OwnerIsCreator.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {ConfirmedOwner} from "./ConfirmedOwner.sol";
/// @title The OwnerIsCreator contract
/// @notice A contract with helpers for basic contract ownership.
contract OwnerIsCreator is ConfirmedOwner {
constructor() ConfirmedOwner(msg.sender) {}
}
"
},
"src/v0.8/keystone/ocr/OCR2Abstract.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol";
abstract contract OCR2Abstract is ITypeAndVersion {
// Maximum number of oracles the offchain reporting protocol is designed for
uint256 internal constant MAX_NUM_ORACLES = 31;
/**
* @notice triggers a new run of the offchain reporting protocol
* @param previousConfigBlockNumber block in which the previous config was set, to simplify historic analysis
* @param configDigest configDigest of this configuration
* @param configCount ordinal number of this config setting among all config settings over the life of this contract
* @param signers ith element is address ith oracle uses to sign a report
* @param transmitters ith element is address ith oracle uses to transmit a report via the transmit method
* @param f maximum number of faulty/dishonest oracles the protocol can tolerate while still working correctly
* @param onchainConfig serialized configuration used by the contract (and possibly oracles)
* @param offchainConfigVersion version of the serialization format used for "offchainConfig" parameter
* @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract
*/
event ConfigSet(
uint32 previousConfigBlockNumber,
bytes32 configDigest,
uint64 configCount,
bytes[] signers,
address[] transmitters,
uint8 f,
bytes onchainConfig,
uint64 offchainConfigVersion,
bytes offchainConfig
);
/**
* @notice sets offchain reporting protocol configuration incl. participating oracles
* @param signers addresses with which oracles sign the reports
* @param transmitters addresses oracles use to transmit the reports
* @param f number of faulty oracles the system can tolerate
* @param onchainConfig serialized configuration used by the contract (and possibly oracles)
* @param offchainConfigVersion version number for offchainEncoding schema
* @param offchainConfig serialized configuration used by the oracles exclusively and only passed through the contract
*/
function setConfig(
bytes[] memory signers,
address[] memory transmitters,
uint8 f,
bytes memory onchainConfig,
uint64 offchainConfigVersion,
bytes memory offchainConfig
) external virtual;
/**
* @notice information about current offchain reporting protocol configuration
* @return configCount ordinal number of current config, out of all configs applied to this contract so far
* @return blockNumber block at which this config was set
* @return configDigest domain-separation tag for current config (see _configDigestFromConfigData)
*/
function latestConfigDetails()
external
view
virtual
returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest);
/**
* @notice optionally emitted to indicate the latest configDigest and epoch for
which a report was successfully transmitted. Alternatively, the contract may
use latestConfigDigestAndEpoch with scanLogs set to false.
*/
event Transmitted(bytes32 configDigest, uint32 epoch);
/**
* @notice optionally returns the latest configDigest and epoch for which a
report was successfully transmitted. Alternatively, the contract may return
scanLogs set to true and use Transmitted events to provide this information
to offchain watchers.
* @return scanLogs indicates whether to rely on the configDigest and epoch
returned or whether to scan logs for the Transmitted event instead.
* @return configDigest
* @return epoch
*/
function latestConfigDigestAndEpoch()
external
view
virtual
returns (bool scanLogs, bytes32 configDigest, uint32 epoch);
/**
* @notice transmit is called to post a new report to the contract
* @param report serialized report, which the signatures are signing.
* @param rs ith element is the R components of the ith signature on report. Must have at most maxNumOracles entries
* @param ss ith element is the S components of the ith signature on report. Must have at most maxNumOracles entries
* @param rawVs ith element is the the V component of the ith signature
*/
function transmit(
// NOTE: If these parameters are changed, expectedMsgDataLength and/or
// TRANSMIT_MSGDATA_CONSTANT_LENGTH_COMPONENT need to be changed accordingly
bytes32[3] calldata reportContext,
bytes calldata report,
bytes32[] calldata rs,
bytes32[] calldata ss,
bytes32 rawVs // signatures
) external virtual;
}
"
},
"src/v0.8/shared/access/ConfirmedOwner.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {ConfirmedOwnerWithProposal} from "./ConfirmedOwnerWithProposal.sol";
/// @title The ConfirmedOwner contract
/// @notice A contract with helpers for basic contract ownership.
contract ConfirmedOwner is ConfirmedOwnerWithProposal {
constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}
}
"
},
"src/v0.8/shared/interfaces/ITypeAndVersion.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface ITypeAndVersion {
function typeAndVersion() external pure returns (string memory);
}
"
},
"src/v0.8/shared/access/ConfirmedOwnerWithProposal.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {IOwnable} from "../interfaces/IOwnable.sol";
/// @title The ConfirmedOwner contract
/// @notice A contract with helpers for basic contract ownership.
contract ConfirmedOwnerWithProposal is IOwnable {
address private s_owner;
address private s_pendingOwner;
event OwnershipTransferRequested(address indexed from, address indexed to);
event OwnershipTransferred(address indexed from, address indexed to);
constructor(address newOwner, address pendingOwner) {
// solhint-disable-next-line gas-custom-errors
require(newOwner != address(0), "Cannot set owner to zero");
s_owner = newOwner;
if (pendingOwner != address(0)) {
_transferOwnership(pendingOwner);
}
}
/// @notice Allows an owner to begin transferring ownership to a new address.
function transferOwnership(address to) public override onlyOwner {
_transferOwnership(to);
}
/// @notice Allows an ownership transfer to be completed by the recipient.
function acceptOwnership() external override {
// solhint-disable-next-line gas-custom-errors
require(msg.sender == s_pendingOwner, "Must be proposed owner");
address oldOwner = s_owner;
s_owner = msg.sender;
s_pendingOwner = address(0);
emit OwnershipTransferred(oldOwner, msg.sender);
}
/// @notice Get the current owner
function owner() public view override returns (address) {
return s_owner;
}
/// @notice validate, transfer ownership, and emit relevant events
function _transferOwnership(address to) private {
// solhint-disable-next-line gas-custom-errors
require(to != msg.sender, "Cannot transfer to self");
s_pendingOwner = to;
emit OwnershipTransferRequested(s_owner, to);
}
/// @notice validate access
function _validateOwnership() internal view {
// solhint-disable-next-line gas-custom-errors
require(msg.sender == s_owner, "Only callable by owner");
}
/// @notice Reverts if called by anyone other than the contract owner.
modifier onlyOwner() {
_validateOwnership();
_;
}
}
"
},
"src/v0.8/shared/interfaces/IOwnable.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IOwnable {
function owner() external returns (address);
function transferOwnership(address recipient) external;
function acceptOwnership() external;
}
"
}
},
"settings": {
"remappings": [
"forge-std/=src/v0.8/vendor/forge-std/src/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@arbitrum/=node_modules/@arbitrum/",
"hardhat/=node_modules/hardhat/",
"@eth-optimism/=node_modules/@eth-optimism/",
"@scroll-tech/=node_modules/@scroll-tech/",
"@zksync/=node_modules/@zksync/",
"@offchainlabs/=node_modules/@offchainlabs/"
],
"optimizer": {
"enabled": true,
"runs": 100000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}
}}
Submitted on: 2025-11-06 17:33:11
Comments
Log in to comment.
No comments yet.