Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 207,278 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Report | 7942972 | 1 min ago | IN | 0 ETH | 0.00001208 | ||||
Report | 7942971 | 1 min ago | IN | 0 ETH | 0.00001205 | ||||
Report | 7942970 | 1 min ago | IN | 0 ETH | 0.00008594 | ||||
Report | 7942970 | 1 min ago | IN | 0 ETH | 0.00008601 | ||||
Report | 7942969 | 1 min ago | IN | 0 ETH | 0.00012681 | ||||
Report | 7942969 | 1 min ago | IN | 0 ETH | 0.00012692 | ||||
Report | 7942968 | 2 mins ago | IN | 0 ETH | 0.00011047 | ||||
Report | 7942968 | 2 mins ago | IN | 0 ETH | 0.00010322 | ||||
Report | 7942968 | 2 mins ago | IN | 0 ETH | 0.00015292 | ||||
Report | 7942963 | 3 mins ago | IN | 0 ETH | 0.00012832 | ||||
Report | 7942963 | 3 mins ago | IN | 0 ETH | 0.00012534 | ||||
Report | 7942948 | 6 mins ago | IN | 0 ETH | 0.00013082 | ||||
Report | 7942946 | 6 mins ago | IN | 0 ETH | 0.00008523 | ||||
Report | 7942946 | 6 mins ago | IN | 0 ETH | 0.00008521 | ||||
Report | 7942945 | 6 mins ago | IN | 0 ETH | 0.00011001 | ||||
Report | 7942945 | 6 mins ago | IN | 0 ETH | 0.00011004 | ||||
Report | 7942944 | 6 mins ago | IN | 0 ETH | 0.00012636 | ||||
Report | 7942944 | 6 mins ago | IN | 0 ETH | 0.00012638 | ||||
Report | 7942943 | 7 mins ago | IN | 0 ETH | 0.00015278 | ||||
Report | 7942943 | 7 mins ago | IN | 0 ETH | 0.00015275 | ||||
Report | 7942933 | 9 mins ago | IN | 0 ETH | 0.00018966 | ||||
Report | 7942933 | 9 mins ago | IN | 0 ETH | 0.00018527 | ||||
Report | 7942923 | 11 mins ago | IN | 0 ETH | 0.0001107 | ||||
Report | 7942919 | 11 mins ago | IN | 0 ETH | 0.00008583 | ||||
Report | 7942919 | 11 mins ago | IN | 0 ETH | 0.00008585 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0xd89eF599...4A3AA71d4 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
KeystoneForwarder
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {IReceiver} from "./interfaces/IReceiver.sol"; import {IRouter} from "./interfaces/IRouter.sol"; import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; import {OwnerIsCreator} from "../shared/access/OwnerIsCreator.sol"; import {ERC165Checker} from "../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/introspection/ERC165Checker.sol"; /// @notice This is an entry point for `write_${chain}` Target capability. It allows nodes to /// determine if reports have been processed (successfully or not) in a decentralized and /// product-agnostic way by recording processed reports. contract KeystoneForwarder is OwnerIsCreator, ITypeAndVersion, IRouter { /// @notice This error is returned when the report is shorter than REPORT_METADATA_LENGTH, /// which is the minimum length of a report. error InvalidReport(); /// @notice This error is thrown whenever trying to set a config with a fault tolerance of 0. error FaultToleranceMustBePositive(); /// @notice This error is thrown whenever configuration provides more signers than the maximum allowed number. /// @param numSigners The number of signers who have signed the report /// @param maxSigners The maximum number of signers that can sign a report error ExcessSigners(uint256 numSigners, uint256 maxSigners); /// @notice This error is thrown whenever a configuration is provided with less than the minimum number of signers. /// @param numSigners The number of signers provided /// @param minSigners The minimum number of signers expected error InsufficientSigners(uint256 numSigners, uint256 minSigners); /// @notice This error is thrown whenever a duplicate signer address is provided in the configuration. /// @param signer The signer address that was duplicated. error DuplicateSigner(address signer); /// @notice This error is thrown whenever a report has an incorrect number of signatures. /// @param expected The number of signatures expected, F + 1 /// @param received The number of signatures received error InvalidSignatureCount(uint256 expected, uint256 received); /// @notice This error is thrown whenever a report specifies a configuration that does not exist. /// @param configId (uint64(donId) << 32) | configVersion error InvalidConfig(uint64 configId); /// @notice This error is thrown whenever a signer address is not in the configuration or /// when trying to set a zero address as a signer. /// @param signer The signer address that was not in the configuration error InvalidSigner(address signer); /// @notice This error is thrown whenever a signature is invalid. /// @param signature The signature that was invalid error InvalidSignature(bytes signature); /// @notice Contains the signing address of each oracle struct OracleSet { uint8 f; // Number of faulty nodes allowed address[] signers; mapping(address signer => uint256 position) _positions; // 1-indexed to detect unset values } struct Transmission { address transmitter; // This is true if the receiver is not a contract or does not implement the `IReceiver` interface. bool invalidReceiver; // Whether the transmission attempt was successful. If `false`, the transmission can be retried // with an increased gas limit. bool success; // The amount of gas allocated for the `IReceiver.onReport` call. uint80 allows storing gas for known EVM block // gas limits. Ensures that the minimum gas requested by the user is available during the transmission attempt. // If the transmission fails (indicated by a `false` success state), it can be retried with an increased gas limit. uint80 gasLimit; } /// @notice Emitted when a report is processed /// @param result The result of the attempted delivery. True if successful. event ReportProcessed( address indexed receiver, bytes32 indexed workflowExecutionId, bytes2 indexed reportId, bool result ); /// @notice Contains the configuration for each DON ID /// configId (uint64(donId) << 32) | configVersion mapping(uint64 configId => OracleSet oracleSet) internal s_configs; event ConfigSet(uint32 indexed donId, uint32 indexed configVersion, uint8 f, address[] signers); string public constant override typeAndVersion = "KeystoneForwarder 1.0.0"; constructor() OwnerIsCreator() { s_forwarders[address(this)] = true; } uint256 internal constant MAX_ORACLES = 31; uint256 internal constant METADATA_LENGTH = 109; uint256 internal constant FORWARDER_METADATA_LENGTH = 45; uint256 internal constant SIGNATURE_LENGTH = 65; /// @dev This is the gas required to store `success` after the report is processed. /// It is a warm storage write because of the packed struct. In practice it will cost less. uint256 internal constant INTERNAL_GAS_REQUIREMENTS_AFTER_REPORT = 5_000; /// @dev This is the gas required to store the transmission struct and perform other checks. uint256 internal constant INTERNAL_GAS_REQUIREMENTS = 25_000 + INTERNAL_GAS_REQUIREMENTS_AFTER_REPORT; /// @dev This is the minimum gas required to route a report. This includes internal gas requirements /// as well as the minimum gas that the user contract will receive. 30k * 3 gas is to account for /// cases where consumers need close to the 30k limit provided in the supportsInterface check. uint256 internal constant MINIMUM_GAS_LIMIT = INTERNAL_GAS_REQUIREMENTS + 30_000 * 3 + 10_000; // ================================================================ // │ Router │ // ================================================================ mapping(address forwarder => bool isForwarder) internal s_forwarders; mapping(bytes32 transmissionId => Transmission transmission) internal s_transmissions; function addForwarder(address forwarder) external onlyOwner { s_forwarders[forwarder] = true; emit ForwarderAdded(forwarder); } function removeForwarder(address forwarder) external onlyOwner { s_forwarders[forwarder] = false; emit ForwarderRemoved(forwarder); } function route( bytes32 transmissionId, address transmitter, address receiver, bytes calldata metadata, bytes calldata validatedReport ) public returns (bool) { if (!s_forwarders[msg.sender]) revert UnauthorizedForwarder(); uint256 gasLimit = gasleft() - INTERNAL_GAS_REQUIREMENTS; if (gasLimit < MINIMUM_GAS_LIMIT) revert InsufficientGasForRouting(transmissionId); Transmission memory transmission = s_transmissions[transmissionId]; if (transmission.success || transmission.invalidReceiver) revert AlreadyAttempted(transmissionId); s_transmissions[transmissionId].transmitter = transmitter; s_transmissions[transmissionId].gasLimit = uint80(gasLimit); // This call can consume up to 90k gas. if (!ERC165Checker.supportsInterface(receiver, type(IReceiver).interfaceId)) { s_transmissions[transmissionId].invalidReceiver = true; return false; } bool success; bytes memory payload = abi.encodeCall(IReceiver.onReport, (metadata, validatedReport)); uint256 remainingGas = gasleft() - INTERNAL_GAS_REQUIREMENTS_AFTER_REPORT; assembly { // call and return whether we succeeded. ignore return data // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) success := call(remainingGas, receiver, 0, add(payload, 0x20), mload(payload), 0x0, 0x0) } if (success) { s_transmissions[transmissionId].success = true; } return success; } function getTransmissionId( address receiver, bytes32 workflowExecutionId, bytes2 reportId ) public pure returns (bytes32) { // This is slightly cheaper compared to `keccak256(abi.encode(receiver, workflowExecutionId, reportId));` return keccak256(bytes.concat(bytes20(uint160(receiver)), workflowExecutionId, reportId)); } function getTransmissionInfo( address receiver, bytes32 workflowExecutionId, bytes2 reportId ) external view returns (TransmissionInfo memory) { bytes32 transmissionId = getTransmissionId(receiver, workflowExecutionId, reportId); Transmission memory transmission = s_transmissions[transmissionId]; TransmissionState state; if (transmission.transmitter == address(0)) { state = IRouter.TransmissionState.NOT_ATTEMPTED; } else if (transmission.invalidReceiver) { state = IRouter.TransmissionState.INVALID_RECEIVER; } else { state = transmission.success ? IRouter.TransmissionState.SUCCEEDED : IRouter.TransmissionState.FAILED; } return TransmissionInfo({ gasLimit: transmission.gasLimit, invalidReceiver: transmission.invalidReceiver, state: state, success: transmission.success, transmissionId: transmissionId, transmitter: transmission.transmitter }); } /// @notice Get transmitter of a given report or 0x0 if it wasn't transmitted yet function getTransmitter( address receiver, bytes32 workflowExecutionId, bytes2 reportId ) external view returns (address) { return s_transmissions[getTransmissionId(receiver, workflowExecutionId, reportId)].transmitter; } function isForwarder(address forwarder) external view returns (bool) { return s_forwarders[forwarder]; } // ================================================================ // │ Forwarder │ // ================================================================ function setConfig(uint32 donId, uint32 configVersion, uint8 f, address[] calldata signers) external onlyOwner { if (f == 0) revert FaultToleranceMustBePositive(); if (signers.length > MAX_ORACLES) revert ExcessSigners(signers.length, MAX_ORACLES); if (signers.length <= 3 * f) revert InsufficientSigners(signers.length, 3 * f + 1); uint64 configId = (uint64(donId) << 32) | configVersion; // remove any old signer addresses for (uint256 i = 0; i < s_configs[configId].signers.length; ++i) { delete s_configs[configId]._positions[s_configs[configId].signers[i]]; } // add new signer addresses for (uint256 i = 0; i < signers.length; ++i) { // assign indices, detect duplicates address signer = signers[i]; if (signer == address(0)) revert InvalidSigner(signer); if (s_configs[configId]._positions[signer] != 0) revert DuplicateSigner(signer); s_configs[configId]._positions[signer] = i + 1; } s_configs[configId].signers = signers; s_configs[configId].f = f; emit ConfigSet(donId, configVersion, f, signers); } function clearConfig(uint32 donId, uint32 configVersion) external onlyOwner { // We are not removing old signer positions, because it is sufficient to // clear the f value for `report` function. If we decide to restore // the configId in the future, the setConfig function clears the positions. s_configs[(uint64(donId) << 32) | configVersion].f = 0; emit ConfigSet(donId, configVersion, 0, new address[](0)); } // send a report to receiver function report( address receiver, bytes calldata rawReport, bytes calldata reportContext, bytes[] calldata signatures ) external { if (rawReport.length < METADATA_LENGTH) { revert InvalidReport(); } bytes32 workflowExecutionId; bytes2 reportId; { uint64 configId; (workflowExecutionId, configId, reportId) = _getMetadata(rawReport); OracleSet storage config = s_configs[configId]; uint8 f = config.f; // f can never be 0, so this means the config doesn't actually exist if (f == 0) revert InvalidConfig(configId); if (f + 1 != signatures.length) revert InvalidSignatureCount(f + 1, signatures.length); // validate signatures bytes32 completeHash = keccak256(abi.encodePacked(keccak256(rawReport), reportContext)); address[MAX_ORACLES + 1] memory signed; for (uint256 i = 0; i < signatures.length; ++i) { bytes calldata signature = signatures[i]; if (signature.length != SIGNATURE_LENGTH) revert InvalidSignature(signature); address signer = ecrecover( completeHash, uint8(signature[64]) + 27, bytes32(signature[0:32]), bytes32(signature[32:64]) ); // validate signer is trusted and signature is unique uint256 index = config._positions[signer]; if (index == 0) revert InvalidSigner(signer); // index is 1-indexed so we can detect unset signers if (signed[index] != address(0)) revert DuplicateSigner(signer); signed[index] = signer; } } bool success = this.route( getTransmissionId(receiver, workflowExecutionId, reportId), msg.sender, receiver, rawReport[FORWARDER_METADATA_LENGTH:METADATA_LENGTH], rawReport[METADATA_LENGTH:] ); emit ReportProcessed(receiver, workflowExecutionId, reportId, success); } // solhint-disable-next-line chainlink-solidity/explicit-returns function _getMetadata( bytes memory rawReport ) internal pure returns (bytes32 workflowExecutionId, uint64 configId, bytes2 reportId) { // (first 32 bytes of memory contain length of the report) // version offset 32, size 1 // workflow_execution_id offset 33, size 32 // timestamp offset 65, size 4 // don_id offset 69, size 4 // don_config_version, offset 73, size 4 // workflow_cid offset 77, size 32 // workflow_name offset 109, size 10 // workflow_owner offset 119, size 20 // report_id offset 139, size 2 assembly { workflowExecutionId := mload(add(rawReport, 33)) // shift right by 24 bytes to get the combined don_id and don_config_version configId := shr(mul(24, 8), mload(add(rawReport, 69))) reportId := mload(add(rawReport, 139)) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC165} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol"; /// @title IReceiver - receives keystone reports /// @notice Implementations must support the IReceiver interface through ERC165. interface IReceiver is IERC165 { /// @notice Handles incoming keystone reports. /// @dev If this function call reverts, it can be retried with a higher gas /// limit. The receiver is responsible for discarding stale reports. /// @param metadata Report's metadata. /// @param report Workflow report. function onReport(bytes calldata metadata, bytes calldata report) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @title IRouter - delivers keystone reports to receiver interface IRouter { error UnauthorizedForwarder(); /// @dev Thrown when the gas limit is insufficient for handling state after /// calling the receiver function. error InsufficientGasForRouting(bytes32 transmissionId); error AlreadyAttempted(bytes32 transmissionId); event ForwarderAdded(address indexed forwarder); event ForwarderRemoved(address indexed forwarder); enum TransmissionState { NOT_ATTEMPTED, SUCCEEDED, INVALID_RECEIVER, FAILED } struct TransmissionInfo { bytes32 transmissionId; TransmissionState state; address transmitter; // This is true if the receiver is not a contract or does not implement the // `IReceiver` interface. bool invalidReceiver; // Whether the transmission attempt was successful. If `false`, the // transmission can be retried with an increased gas limit. bool success; // The amount of gas allocated for the `IReceiver.onReport` call. uint80 // allows storing gas for known EVM block gas limits. // Ensures that the minimum gas requested by the user is available during // the transmission attempt. If the transmission fails (indicated by a // `false` success state), it can be retried with an increased gas limit. uint80 gasLimit; } function addForwarder(address forwarder) external; function removeForwarder(address forwarder) external; function route( bytes32 transmissionId, address transmitter, address receiver, bytes calldata metadata, bytes calldata report ) external returns (bool); function getTransmissionId( address receiver, bytes32 workflowExecutionId, bytes2 reportId ) external pure returns (bytes32); function getTransmissionInfo( address receiver, bytes32 workflowExecutionId, bytes2 reportId ) external view returns (TransmissionInfo memory); function getTransmitter( address receiver, bytes32 workflowExecutionId, bytes2 reportId ) external view returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface ITypeAndVersion { function typeAndVersion() external pure returns (string memory); }
// 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) {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.2) (utils/introspection/ERC165Checker.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface. */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return supportsERC165InterfaceUnchecked(account, type(IERC165).interfaceId) && !supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. * * _Available since v3.4._ */ function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * * Some precompiled contracts will falsely indicate support for a given interface, so caution * should be exercised when using this function. * * Interface identification is specified in ERC-165. */ function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) { // prepare call bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId); // perform static call bool success; uint256 returnSize; uint256 returnValue; assembly { success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) returnSize := returndatasize() returnValue := mload(0x00) } return success && returnSize >= 0x20 && returnValue > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// 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)) {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// 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(); _; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IOwnable { function owner() external returns (address); function transferOwnership(address recipient) external; function acceptOwnership() external; }
{ "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/" ], "optimizer": { "enabled": true, "runs": 1000000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"transmissionId","type":"bytes32"}],"name":"AlreadyAttempted","type":"error"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"DuplicateSigner","type":"error"},{"inputs":[{"internalType":"uint256","name":"numSigners","type":"uint256"},{"internalType":"uint256","name":"maxSigners","type":"uint256"}],"name":"ExcessSigners","type":"error"},{"inputs":[],"name":"FaultToleranceMustBePositive","type":"error"},{"inputs":[{"internalType":"bytes32","name":"transmissionId","type":"bytes32"}],"name":"InsufficientGasForRouting","type":"error"},{"inputs":[{"internalType":"uint256","name":"numSigners","type":"uint256"},{"internalType":"uint256","name":"minSigners","type":"uint256"}],"name":"InsufficientSigners","type":"error"},{"inputs":[{"internalType":"uint64","name":"configId","type":"uint64"}],"name":"InvalidConfig","type":"error"},{"inputs":[],"name":"InvalidReport","type":"error"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"InvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"received","type":"uint256"}],"name":"InvalidSignatureCount","type":"error"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"InvalidSigner","type":"error"},{"inputs":[],"name":"UnauthorizedForwarder","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint32","name":"donId","type":"uint32"},{"indexed":true,"internalType":"uint32","name":"configVersion","type":"uint32"},{"indexed":false,"internalType":"uint8","name":"f","type":"uint8"},{"indexed":false,"internalType":"address[]","name":"signers","type":"address[]"}],"name":"ConfigSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"forwarder","type":"address"}],"name":"ForwarderAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"forwarder","type":"address"}],"name":"ForwarderRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":true,"internalType":"bytes32","name":"workflowExecutionId","type":"bytes32"},{"indexed":true,"internalType":"bytes2","name":"reportId","type":"bytes2"},{"indexed":false,"internalType":"bool","name":"result","type":"bool"}],"name":"ReportProcessed","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"addForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"donId","type":"uint32"},{"internalType":"uint32","name":"configVersion","type":"uint32"}],"name":"clearConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"workflowExecutionId","type":"bytes32"},{"internalType":"bytes2","name":"reportId","type":"bytes2"}],"name":"getTransmissionId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"workflowExecutionId","type":"bytes32"},{"internalType":"bytes2","name":"reportId","type":"bytes2"}],"name":"getTransmissionInfo","outputs":[{"components":[{"internalType":"bytes32","name":"transmissionId","type":"bytes32"},{"internalType":"enum IRouter.TransmissionState","name":"state","type":"uint8"},{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"bool","name":"invalidReceiver","type":"bool"},{"internalType":"bool","name":"success","type":"bool"},{"internalType":"uint80","name":"gasLimit","type":"uint80"}],"internalType":"struct IRouter.TransmissionInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes32","name":"workflowExecutionId","type":"bytes32"},{"internalType":"bytes2","name":"reportId","type":"bytes2"}],"name":"getTransmitter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"isForwarder","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"forwarder","type":"address"}],"name":"removeForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"rawReport","type":"bytes"},{"internalType":"bytes","name":"reportContext","type":"bytes"},{"internalType":"bytes[]","name":"signatures","type":"bytes[]"}],"name":"report","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"transmissionId","type":"bytes32"},{"internalType":"address","name":"transmitter","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"metadata","type":"bytes"},{"internalType":"bytes","name":"validatedReport","type":"bytes"}],"name":"route","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"donId","type":"uint32"},{"internalType":"uint32","name":"configVersion","type":"uint32"},{"internalType":"uint8","name":"f","type":"uint8"},{"internalType":"address[]","name":"signers","type":"address[]"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"typeAndVersion","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c806379ba50971161008c578063abcef55411610066578063abcef5541461035d578063ee59d26c14610396578063ef6e17a0146103a9578063f2fde38b146103bc57600080fd5b806379ba50971461025e5780638864b864146102665780638da5cb5b1461033f57600080fd5b8063272cbd93116100c8578063272cbd9314610179578063354bdd66146101995780634d93172d146102385780635c41d2fe1461024b57600080fd5b806311289565146100ef578063181f5a7714610104578063233fd52d14610156575b600080fd5b6101026100fd366004611a33565b6103cf565b005b6101406040518060400160405280601781526020017f4b657973746f6e65466f7277617264657220312e302e3000000000000000000081525081565b60405161014d9190611ade565b60405180910390f35b610169610164366004611b4b565b610989565b604051901515815260200161014d565b61018c610187366004611bd3565b610d4a565b60405161014d9190611c67565b61022a6101a7366004611bd3565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390527fffff000000000000000000000000000000000000000000000000000000000000821660548201526000906056016040516020818303038152906040528051906020012090509392505050565b60405190815260200161014d565b610102610246366004611d0f565b610f50565b610102610259366004611d0f565b610fcc565b61010261104b565b61031a610274366004611bd3565b6040805160609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660208086019190915260348501939093527fffff000000000000000000000000000000000000000000000000000000000000919091166054840152805160368185030181526056909301815282519282019290922060009081526004909152205473ffffffffffffffffffffffffffffffffffffffff1690565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161014d565b60005473ffffffffffffffffffffffffffffffffffffffff1661031a565b61016961036b366004611d0f565b73ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205460ff1690565b6101026103a4366004611d3e565b611148565b6101026103b7366004611dbc565b611525565b6101026103ca366004611d0f565b6115c5565b606d85101561040a576040517fb55ac75400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080600061044e89898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506115d992505050565b67ffffffffffffffff8216600090815260026020526040812080549497509195509193509160ff16908190036104c1576040517fdf3b81ea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff841660048201526024015b60405180910390fd5b856104cd826001611e1e565b60ff161461051f576104e0816001611e1e565b6040517fd6022e8e00000000000000000000000000000000000000000000000000000000815260ff9091166004820152602481018790526044016104b8565b60008b8b604051610531929190611e37565b60405190819003812061054a918c908c90602001611e47565b60405160208183030381529060405280519060200120905061056a6118c0565b60005b888110156107ec573660008b8b8481811061058a5761058a611e61565b905060200281019061059c9190611e90565b9092509050604181146105df5781816040517f2adfdc300000000000000000000000000000000000000000000000000000000081526004016104b8929190611f3e565b6000600186848460408181106105f7576105f7611e61565b61060992013560f81c9050601b611e1e565b610617602060008789611f5a565b61062091611f84565b61062e60406020888a611f5a565b61063791611f84565b6040805160008152602081018083529590955260ff909316928401929092526060830152608082015260a0016020604051602081039080840390855afa158015610685573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8116600090815260028c0160205291822054909350915081900361072b576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b600086826020811061073f5761073f611e61565b602002015173ffffffffffffffffffffffffffffffffffffffff16146107a9576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016104b8565b818682602081106107bc576107bc611e61565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015250506001909201915061056d9050565b50506040805160608f901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016602080830191909152603482018990527fffff0000000000000000000000000000000000000000000000000000000000008816605483015282516036818403018152605690920190925280519101206000945030935063233fd52d92509050338d8d8d602d90606d9261088e93929190611f5a565b8f8f606d9080926108a193929190611f5a565b6040518863ffffffff1660e01b81526004016108c39796959493929190611fc0565b6020604051808303816000875af11580156108e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109069190612021565b9050817dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916838b73ffffffffffffffffffffffffffffffffffffffff167f3617b009e9785c42daebadb6d3fb553243a4bf586d07ea72d65d80013ce116b584604051610975911515815260200190565b60405180910390a450505050505050505050565b3360009081526003602052604081205460ff166109d2576040517fd79e123d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006109e26113886161a861204a565b5a6109ed919061205d565b90506109fd6113886161a861204a565b610a0a9062015f9061204a565b610a169061271061204a565b811015610a52576040517f0bfecd63000000000000000000000000000000000000000000000000000000008152600481018a90526024016104b8565b6000898152600460209081526040918290208251608081018452905473ffffffffffffffffffffffffffffffffffffffff8116825274010000000000000000000000000000000000000000810460ff90811615159383019390935275010000000000000000000000000000000000000000008104909216151592810183905276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660608201529080610b0a575080602001515b15610b44576040517fa53dc8ca000000000000000000000000000000000000000000000000000000008152600481018b90526024016104b8565b60008a8152600460205260409020805469ffffffffffffffffffff84167601000000000000000000000000000000000000000000000275ffff000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff8c1617179055610bd9887f805f2132000000000000000000000000000000000000000000000000000000006115f4565b610c3057505050600087815260046020526040812080547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055610d3f565b60008088888888604051602401610c4a9493929190612070565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f805f213200000000000000000000000000000000000000000000000000000000179052905060006113885a610cd2919061205d565b905060008083516020850160008f86f192508215610d375760008d815260046020526040902080547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff1675010000000000000000000000000000000000000000001790555b509093505050505b979650505050505050565b6040805160c0810182526000808252602080830182905282840182905260608084018390526080840183905260a0840183905284519088901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001681830152603481018790527fffff000000000000000000000000000000000000000000000000000000000000861660548201528451603681830301815260568201808752815191840191909120808552600490935285842060d68301909652945473ffffffffffffffffffffffffffffffffffffffff811680875274010000000000000000000000000000000000000000820460ff9081161515607685015275010000000000000000000000000000000000000000008304161515609684015276010000000000000000000000000000000000000000000090910469ffffffffffffffffffff1660b69092019190915292939092909190610ea857506000610ed0565b816020015115610eba57506002610ed0565b8160400151610eca576003610ecd565b60015b90505b6040518060c00160405280848152602001826003811115610ef357610ef3611c38565b8152602001836000015173ffffffffffffffffffffffffffffffffffffffff168152602001836020015115158152602001836040015115158152602001836060015169ffffffffffffffffffff1681525093505050509392505050565b610f58611619565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517fb96d15bf9258c7b8df062753a6a262864611fc7b060a5ee2e57e79b85f898d389190a250565b610fd4611619565b73ffffffffffffffffffffffffffffffffffffffff811660008181526003602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f0ea0ce2c048ff45a4a95f2947879de3fb94abec2f152190400cab2d1272a68e79190a250565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110cc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016104b8565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611150611619565b8260ff1660000361118d576040517f0743bae600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601f8111156111d2576040517f61750f4000000000000000000000000000000000000000000000000000000000815260048101829052601f60248201526044016104b8565b6111dd836003612097565b60ff16811161123b57806111f2846003612097565b6111fd906001611e1e565b6040517f9dd9e6d8000000000000000000000000000000000000000000000000000000008152600481019290925260ff1660248201526044016104b8565b67ffffffff00000000602086901b1663ffffffff85161760005b67ffffffffffffffff82166000908152600260205260409020600101548110156112eb5767ffffffffffffffff82166000908152600260208190526040822060018101805491909201929190849081106112b1576112b1611e61565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812055600101611255565b5060005b8281101561146757600084848381811061130b5761130b611e61565b90506020020160208101906113209190611d0f565b905073ffffffffffffffffffffffffffffffffffffffff8116611387576040517fbf18af4300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b67ffffffffffffffff8316600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff86168552909201905290205415611413576040517fe021c4f200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016104b8565b61141e82600161204a565b67ffffffffffffffff8416600090815260026020818152604080842073ffffffffffffffffffffffffffffffffffffffff909616845294909101905291909120556001016112ef565b5067ffffffffffffffff8116600090815260026020526040902061148f9060010184846118df565b5067ffffffffffffffff81166000908152600260205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff87161790555163ffffffff86811691908816907f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a45590611515908890889088906120b3565b60405180910390a3505050505050565b61152d611619565b63ffffffff818116602084811b67ffffffff00000000168217600090815260028252604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690558051828152928301905291928516917f4120bd3b23957dd423555817d55654d4481b438aa15485c21b4180c784f1a455916040516115b9929190612119565b60405180910390a35050565b6115cd611619565b6115d68161169c565b50565b60218101516045820151608b90920151909260c09290921c91565b60006115ff83611791565b8015611610575061161083836117f5565b90505b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461169a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016104b8565b565b3373ffffffffffffffffffffffffffffffffffffffff82160361171b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016104b8565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006117bd827f01ffc9a7000000000000000000000000000000000000000000000000000000006117f5565b801561161357506117ee827fffffffff000000000000000000000000000000000000000000000000000000006117f5565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d915060005190508280156118ad575060208210155b8015610d3f575015159695505050505050565b6040518061040001604052806020906020820280368337509192915050565b828054828255906000526020600020908101928215611957579160200282015b828111156119575781547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8435161782556020909201916001909101906118ff565b50611963929150611967565b5090565b5b808211156119635760008155600101611968565b803573ffffffffffffffffffffffffffffffffffffffff811681146119a057600080fd5b919050565b60008083601f8401126119b757600080fd5b50813567ffffffffffffffff8111156119cf57600080fd5b6020830191508360208285010111156119e757600080fd5b9250929050565b60008083601f840112611a0057600080fd5b50813567ffffffffffffffff811115611a1857600080fd5b6020830191508360208260051b85010111156119e757600080fd5b60008060008060008060006080888a031215611a4e57600080fd5b611a578861197c565b9650602088013567ffffffffffffffff80821115611a7457600080fd5b611a808b838c016119a5565b909850965060408a0135915080821115611a9957600080fd5b611aa58b838c016119a5565b909650945060608a0135915080821115611abe57600080fd5b50611acb8a828b016119ee565b989b979a50959850939692959293505050565b60006020808352835180602085015260005b81811015611b0c57858101830151858201604001528201611af0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b600080600080600080600060a0888a031215611b6657600080fd5b87359650611b766020890161197c565b9550611b846040890161197c565b9450606088013567ffffffffffffffff80821115611ba157600080fd5b611bad8b838c016119a5565b909650945060808a0135915080821115611bc657600080fd5b50611acb8a828b016119a5565b600080600060608486031215611be857600080fd5b611bf18461197c565b92506020840135915060408401357fffff00000000000000000000000000000000000000000000000000000000000081168114611c2d57600080fd5b809150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b81518152602082015160c082019060048110611cac577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8060208401525073ffffffffffffffffffffffffffffffffffffffff604084015116604083015260608301511515606083015260808301511515608083015260a0830151611d0860a084018269ffffffffffffffffffff169052565b5092915050565b600060208284031215611d2157600080fd5b6116108261197c565b803563ffffffff811681146119a057600080fd5b600080600080600060808688031215611d5657600080fd5b611d5f86611d2a565b9450611d6d60208701611d2a565b9350604086013560ff81168114611d8357600080fd5b9250606086013567ffffffffffffffff811115611d9f57600080fd5b611dab888289016119ee565b969995985093965092949392505050565b60008060408385031215611dcf57600080fd5b611dd883611d2a565b9150611de660208401611d2a565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff818116838216019081111561161357611613611def565b8183823760009101908152919050565b838152818360208301376000910160200190815292915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112611ec557600080fd5b83018035915067ffffffffffffffff821115611ee057600080fd5b6020019150368190038213156119e757600080fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000611f52602083018486611ef5565b949350505050565b60008085851115611f6a57600080fd5b83861115611f7757600080fd5b5050820193919092039150565b80356020831015611613577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b878152600073ffffffffffffffffffffffffffffffffffffffff808916602084015280881660408401525060a0606083015261200060a083018688611ef5565b8281036080840152612013818587611ef5565b9a9950505050505050505050565b60006020828403121561203357600080fd5b8151801515811461204357600080fd5b9392505050565b8082018082111561161357611613611def565b8181038181111561161357611613611def565b604081526000612084604083018688611ef5565b8281036020840152610d3f818587611ef5565b60ff8181168382160290811690818114611d0857611d08611def565b60ff8416815260406020808301829052908201839052600090849060608401835b8681101561210d5773ffffffffffffffffffffffffffffffffffffffff6120fa8561197c565b16825292820192908201906001016120d4565b50979650505050505050565b60006040820160ff8516835260206040602085015281855180845260608601915060208701935060005b8181101561217557845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101612143565b509097965050505050505056fea164736f6c6343000818000a
Loading...
Loading
Loading...
Loading
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.