Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
Contract Name:
ChainlinkFunctionsBeaconV1
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 100000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
import "@chainlink/contracts/src/v0.8/functions/dev/v1_0_0/libraries/FunctionsRequest.sol";
import "@chainlink/contracts/src/v0.8/functions/dev/v1_0_0/FunctionsClient.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "./storage/ProviderStorage.sol";
/**
* @title ChainlinkFunctionsBeaconV1
* @notice ALL RIGHTS RESERVED
* @dev PROPRIETARY AND CONFIDENTIAL
* Unauthorized copying, modification, distribution, or use of this code, via any medium, is strictly prohibited.
* Written by Instruxi, 2024
*
* @notice EXPERIMENTAL CODE - USE AT YOUR OWN RISK
* @dev This smart contract is undergoing a formal audit and meant for demonstration purposes only.
* This code has not undergone a formal security audit and should not be used in production
* without proper review and testing. Users interact with this contract at their own discretion
* and assume all associated risks.
*/
contract ChainlinkFunctionsBeaconV1 is AbstractProviderStorage, FunctionsClient, ReentrancyGuard {
using FunctionsRequest for FunctionsRequest.Request;
bytes32 public donId;
uint64 public subscriptionId;
uint32 public callbackGasLimit;
FunctionsRequest.Location public secretsLocation;
bytes public encryptedSecretsReference;
mapping(bytes32 => address) public requestToRequester;
mapping(address => bool) public authorizedContracts;
event OCRResponse(bytes32 indexed requestId, bytes response);
event RequestFailed(bytes32 indexed requestId, bytes err);
event RequestSent(string data);
event ContractAuthorized(address indexed contractAddress);
event ContractDeauthorized(address indexed contractAddress);
error UnauthorizedContract(address caller);
constructor(
address router,
bytes32 _donId
) FunctionsClient(router) Ownable(msg.sender) ReentrancyGuard() {
if (msg.sender == address(0)) {
revert OwnableInvalidOwner(msg.sender);
}
donId = _donId;
}
modifier onlyAuthorized() {
if (!authorizedContracts[msg.sender]) {
revert UnauthorizedContract(msg.sender);
}
_;
}
function setConfig(
uint64 _subscriptionId,
uint32 _callbackGasLimit,
FunctionsRequest.Location _secretsLocation,
bytes calldata _encryptedSecretsReference
) external nonReentrant onlyOwner {
subscriptionId = _subscriptionId;
callbackGasLimit = _callbackGasLimit;
secretsLocation = _secretsLocation;
encryptedSecretsReference = _encryptedSecretsReference;
}
function authorizeContract(address contractAddress) external nonReentrant onlyOwner {
authorizedContracts[contractAddress] = true;
emit ContractAuthorized(contractAddress);
}
function deauthorizeContract(address contractAddress) external nonReentrant onlyOwner {
authorizedContracts[contractAddress] = false;
emit ContractDeauthorized(contractAddress);
}
function isContractAuthorized(address contractAddress) external view returns (bool) {
return authorizedContracts[contractAddress];
}
function requestComputation(
bytes calldata data,
bytes32 providerHash
) external nonReentrant onlyAuthorized returns (bytes32) {
string memory source = getProviderSource(providerHash);
FunctionsRequest.Request memory req;
req.initializeRequest(
FunctionsRequest.Location.Inline, // Chainlink Functions does not support external URI yet
FunctionsRequest.CodeLanguage.JavaScript,
source
);
req.secretsLocation = secretsLocation;
req.encryptedSecretsReference = encryptedSecretsReference;
string[] memory args = new string[](1);
args[0] = string(data);
req.setArgs(args);
bytes32 requestId = _sendRequest(
req.encodeCBOR(),
subscriptionId,
callbackGasLimit,
donId
);
this.incrementProviderUseCount(providerHash);
requestToRequester[requestId] = msg.sender;
emit RequestSent(args[0]);
return requestId;
}
function fulfillRequest(
bytes32 requestId,
bytes memory response,
bytes memory err
) internal override nonReentrant {
address requester = requestToRequester[requestId];
require(requester != address(0), "Invalid request ID");
if (err.length > 0) {
emit RequestFailed(requestId, err);
} else {
emit OCRResponse(requestId, response);
}
delete requestToRequester[requestId];
(bool success, ) = requester.call(abi.encodeWithSignature(
"oracleCallback(bytes32,bytes,bytes)",
requestId,
response,
err
));
require(success, "Callback failed");
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {IFunctionsRouter} from "./interfaces/IFunctionsRouter.sol";
import {IFunctionsClient} from "./interfaces/IFunctionsClient.sol";
import {FunctionsRequest} from "./libraries/FunctionsRequest.sol";
/// @title The Chainlink Functions client contract
/// @notice Contract developers can inherit this contract in order to make Chainlink Functions requests
abstract contract FunctionsClient is IFunctionsClient {
using FunctionsRequest for FunctionsRequest.Request;
IFunctionsRouter internal immutable i_router;
event RequestSent(bytes32 indexed id);
event RequestFulfilled(bytes32 indexed id);
error OnlyRouterCanFulfill();
constructor(address router) {
i_router = IFunctionsRouter(router);
}
/// @notice Sends a Chainlink Functions request
/// @param data The CBOR encoded bytes data for a Functions request
/// @param subscriptionId The subscription ID that will be charged to service the request
/// @param callbackGasLimit the amount of gas that will be available for the fulfillment callback
/// @return requestId The generated request ID for this request
function _sendRequest(
bytes memory data,
uint64 subscriptionId,
uint32 callbackGasLimit,
bytes32 donId
) internal returns (bytes32) {
bytes32 requestId = i_router.sendRequest(
subscriptionId,
data,
FunctionsRequest.REQUEST_DATA_VERSION,
callbackGasLimit,
donId
);
emit RequestSent(requestId);
return requestId;
}
/// @notice User defined function to handle a response from the DON
/// @param requestId The request ID, returned by sendRequest()
/// @param response Aggregated response from the execution of the user's source code
/// @param err Aggregated error from the execution of the user code or from the execution pipeline
/// @dev Either response or error parameter will be set, but never both
function fulfillRequest(bytes32 requestId, bytes memory response, bytes memory err) internal virtual;
/// @inheritdoc IFunctionsClient
function handleOracleFulfillment(bytes32 requestId, bytes memory response, bytes memory err) external override {
if (msg.sender != address(i_router)) {
revert OnlyRouterCanFulfill();
}
fulfillRequest(requestId, response, err);
emit RequestFulfilled(requestId);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
/// @title Chainlink Functions client interface.
interface IFunctionsClient {
/// @notice Chainlink Functions response handler called by the Functions Router
/// during fullilment from the designated transmitter node in an OCR round.
/// @param requestId The requestId returned by FunctionsClient.sendRequest().
/// @param response Aggregated response from the request's source code.
/// @param err Aggregated error either from the request's source code or from the execution pipeline.
/// @dev Either response or error parameter will be set, but never both.
function handleOracleFulfillment(bytes32 requestId, bytes memory response, bytes memory err) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {FunctionsResponse} from "../libraries/FunctionsResponse.sol";
/// @title Chainlink Functions Router interface.
interface IFunctionsRouter {
/// @notice The identifier of the route to retrieve the address of the access control contract
/// The access control contract controls which accounts can manage subscriptions
/// @return id - bytes32 id that can be passed to the "getContractById" of the Router
function getAllowListId() external view returns (bytes32);
/// @notice Set the identifier of the route to retrieve the address of the access control contract
/// The access control contract controls which accounts can manage subscriptions
function setAllowListId(bytes32 allowListId) external;
/// @notice Get the flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network
/// @return adminFee
function getAdminFee() external view returns (uint72 adminFee);
/// @notice Sends a request using the provided subscriptionId
/// @param subscriptionId - A unique subscription ID allocated by billing system,
/// a client can make requests from different contracts referencing the same subscription
/// @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request
/// @param dataVersion - Gas limit for the fulfillment callback
/// @param callbackGasLimit - Gas limit for the fulfillment callback
/// @param donId - An identifier used to determine which route to send the request along
/// @return requestId - A unique request identifier
function sendRequest(
uint64 subscriptionId,
bytes calldata data,
uint16 dataVersion,
uint32 callbackGasLimit,
bytes32 donId
) external returns (bytes32);
/// @notice Sends a request to the proposed contracts
/// @param subscriptionId - A unique subscription ID allocated by billing system,
/// a client can make requests from different contracts referencing the same subscription
/// @param data - CBOR encoded Chainlink Functions request data, use FunctionsClient API to encode a request
/// @param dataVersion - Gas limit for the fulfillment callback
/// @param callbackGasLimit - Gas limit for the fulfillment callback
/// @param donId - An identifier used to determine which route to send the request along
/// @return requestId - A unique request identifier
function sendRequestToProposed(
uint64 subscriptionId,
bytes calldata data,
uint16 dataVersion,
uint32 callbackGasLimit,
bytes32 donId
) external returns (bytes32);
/// @notice Fulfill the request by:
/// - calling back the data that the Oracle returned to the client contract
/// - pay the DON for processing the request
/// @dev Only callable by the Coordinator contract that is saved in the commitment
/// @param response response data from DON consensus
/// @param err error from DON consensus
/// @param juelsPerGas - current rate of juels/gas
/// @param costWithoutFulfillment - The cost of processing the request (in Juels of LINK ), without fulfillment
/// @param transmitter - The Node that transmitted the OCR report
/// @param commitment - The parameters of the request that must be held consistent between request and response time
/// @return fulfillResult -
/// @return callbackGasCostJuels -
function fulfill(
bytes memory response,
bytes memory err,
uint96 juelsPerGas,
uint96 costWithoutFulfillment,
address transmitter,
FunctionsResponse.Commitment memory commitment
) external returns (FunctionsResponse.FulfillResult, uint96);
/// @notice Validate requested gas limit is below the subscription max.
/// @param subscriptionId subscription ID
/// @param callbackGasLimit desired callback gas limit
function isValidCallbackGasLimit(uint64 subscriptionId, uint32 callbackGasLimit) external view;
/// @notice Get the current contract given an ID
/// @param id A bytes32 identifier for the route
/// @return contract The current contract address
function getContractById(bytes32 id) external view returns (address);
/// @notice Get the proposed next contract given an ID
/// @param id A bytes32 identifier for the route
/// @return contract The current or proposed contract address
function getProposedContractById(bytes32 id) external view returns (address);
/// @notice Return the latest proprosal set
/// @return ids The identifiers of the contracts to update
/// @return to The addresses of the contracts that will be updated to
function getProposedContractSet() external view returns (bytes32[] memory, address[] memory);
/// @notice Proposes one or more updates to the contract routes
/// @dev Only callable by owner
function proposeContractsUpdate(bytes32[] memory proposalSetIds, address[] memory proposalSetAddresses) external;
/// @notice Updates the current contract routes to the proposed contracts
/// @dev Only callable by owner
function updateContracts() external;
/// @dev Puts the system into an emergency stopped state.
/// @dev Only callable by owner
function pause() external;
/// @dev Takes the system out of an emergency stopped state.
/// @dev Only callable by owner
function unpause() external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {FunctionsResponse} from "../libraries/FunctionsResponse.sol";
/// @title Chainlink Functions Subscription interface.
interface IFunctionsSubscriptions {
struct Subscription {
uint96 balance; // ═════════╗ Common LINK balance that is controlled by the Router to be used for all consumer requests.
address owner; // ══════════╝ The owner can fund/withdraw/cancel the subscription.
uint96 blockedBalance; // ══╗ LINK balance that is reserved to pay for pending consumer requests.
address proposedOwner; // ══╝ For safely transferring sub ownership.
address[] consumers; // ════╸ Client contracts that can use the subscription
bytes32 flags; // ══════════╸ Per-subscription flags
}
struct Consumer {
bool allowed; // ══════════════╗ Owner can fund/withdraw/cancel the sub.
uint64 initiatedRequests; // ║ The number of requests that have been started
uint64 completedRequests; // ══╝ The number of requests that have successfully completed or timed out
}
/// @notice Get details about a subscription.
/// @param subscriptionId - the ID of the subscription
/// @return subscription - see IFunctionsSubscriptions.Subscription for more information on the structure
function getSubscription(uint64 subscriptionId) external view returns (Subscription memory);
/// @notice Retrieve details about multiple subscriptions using an inclusive range
/// @param subscriptionIdStart - the ID of the subscription to start the range at
/// @param subscriptionIdEnd - the ID of the subscription to end the range at
/// @return subscriptions - see IFunctionsSubscriptions.Subscription for more information on the structure
function getSubscriptionsInRange(
uint64 subscriptionIdStart,
uint64 subscriptionIdEnd
) external view returns (Subscription[] memory);
/// @notice Get details about a consumer of a subscription.
/// @param client - the consumer contract address
/// @param subscriptionId - the ID of the subscription
/// @return consumer - see IFunctionsSubscriptions.Consumer for more information on the structure
function getConsumer(address client, uint64 subscriptionId) external view returns (Consumer memory);
/// @notice Get details about the total amount of LINK within the system
/// @return totalBalance - total Juels of LINK held by the contract
function getTotalBalance() external view returns (uint96);
/// @notice Get details about the total number of subscription accounts
/// @return count - total number of subscriptions in the system
function getSubscriptionCount() external view returns (uint64);
/// @notice Time out all expired requests: unlocks funds and removes the ability for the request to be fulfilled
/// @param requestsToTimeoutByCommitment - A list of request commitments to time out
/// @dev The commitment can be found on the "OracleRequest" event created when sending the request.
function timeoutRequests(FunctionsResponse.Commitment[] calldata requestsToTimeoutByCommitment) external;
/// @notice Oracle withdraw LINK earned through fulfilling requests
/// @notice If amount is 0 the full balance will be withdrawn
/// @notice Both signing and transmitting wallets will have a balance to withdraw
/// @param recipient where to send the funds
/// @param amount amount to withdraw
function oracleWithdraw(address recipient, uint96 amount) external;
/// @notice Owner cancel subscription, sends remaining link directly to the subscription owner.
/// @dev Only callable by the Router Owner
/// @param subscriptionId subscription id
/// @dev notably can be called even if there are pending requests, outstanding ones may fail onchain
function ownerCancelSubscription(uint64 subscriptionId) external;
/// @notice Recover link sent with transfer instead of transferAndCall.
/// @dev Only callable by the Router Owner
/// @param to address to send link to
function recoverFunds(address to) external;
/// @notice Create a new subscription.
/// @return subscriptionId - A unique subscription id.
/// @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
/// @dev Note to fund the subscription, use transferAndCall. For example
/// @dev LINKTOKEN.transferAndCall(
/// @dev address(ROUTER),
/// @dev amount,
/// @dev abi.encode(subscriptionId));
function createSubscription() external returns (uint64);
/// @notice Create a new subscription and add a consumer.
/// @return subscriptionId - A unique subscription id.
/// @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
/// @dev Note to fund the subscription, use transferAndCall. For example
/// @dev LINKTOKEN.transferAndCall(
/// @dev address(ROUTER),
/// @dev amount,
/// @dev abi.encode(subscriptionId));
function createSubscriptionWithConsumer(address consumer) external returns (uint64 subscriptionId);
/// @notice Propose a new owner for a subscription.
/// @dev Only callable by the Subscription's owner
/// @param subscriptionId - ID of the subscription
/// @param newOwner - proposed new owner of the subscription
function proposeSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external;
/// @notice Accept an ownership transfer.
/// @param subscriptionId - ID of the subscription
/// @dev will revert if original owner of subscriptionId has not requested that msg.sender become the new owner.
function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external;
/// @notice Remove a consumer from a Chainlink Functions subscription.
/// @dev Only callable by the Subscription's owner
/// @param subscriptionId - ID of the subscription
/// @param consumer - Consumer to remove from the subscription
function removeConsumer(uint64 subscriptionId, address consumer) external;
/// @notice Add a consumer to a Chainlink Functions subscription.
/// @dev Only callable by the Subscription's owner
/// @param subscriptionId - ID of the subscription
/// @param consumer - New consumer which can use the subscription
function addConsumer(uint64 subscriptionId, address consumer) external;
/// @notice Cancel a subscription
/// @dev Only callable by the Subscription's owner
/// @param subscriptionId - ID of the subscription
/// @param to - Where to send the remaining LINK to
function cancelSubscription(uint64 subscriptionId, address to) external;
/// @notice Check to see if there exists a request commitment for all consumers for a given sub.
/// @param subscriptionId - ID of the subscription
/// @return true if there exists at least one unfulfilled request for the subscription, false otherwise.
/// @dev Looping is bounded to MAX_CONSUMERS*(number of DONs).
/// @dev Used to disable subscription canceling while outstanding request are present.
function pendingRequestExists(uint64 subscriptionId) external view returns (bool);
/// @notice Set subscription specific flags for a subscription.
/// Each byte of the flag is used to represent a resource tier that the subscription can utilize.
/// @param subscriptionId - ID of the subscription
/// @param flags - desired flag values
function setFlags(uint64 subscriptionId, bytes32 flags) external;
/// @notice Get flags for a given subscription.
/// @param subscriptionId - ID of the subscription
/// @return flags - current flag values
function getFlags(uint64 subscriptionId) external view returns (bytes32);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {CBOR} from "../../../../vendor/solidity-cborutils/v2.0.0/CBOR.sol";
/// @title Library for encoding the input data of a Functions request into CBOR
library FunctionsRequest {
using CBOR for CBOR.CBORBuffer;
uint16 public constant REQUEST_DATA_VERSION = 1;
uint256 internal constant DEFAULT_BUFFER_SIZE = 256;
enum Location {
Inline, // Provided within the Request
Remote, // Hosted through remote location that can be accessed through a provided URL
DONHosted // Hosted on the DON's storage
}
enum CodeLanguage {
JavaScript
// In future version we may add other languages
}
struct Request {
Location codeLocation; // ════════════╸ The location of the source code that will be executed on each node in the DON
Location secretsLocation; // ═════════╸ The location of secrets that will be passed into the source code. *Only Remote secrets are supported
CodeLanguage language; // ════════════╸ The coding language that the source code is written in
string source; // ════════════════════╸ Raw source code for Request.codeLocation of Location.Inline, URL for Request.codeLocation of Location.Remote, or slot decimal number for Request.codeLocation of Location.DONHosted
bytes encryptedSecretsReference; // ══╸ Encrypted URLs for Request.secretsLocation of Location.Remote (use addSecretsReference()), or CBOR encoded slotid+version for Request.secretsLocation of Location.DONHosted (use addDONHostedSecrets())
string[] args; // ════════════════════╸ String arguments that will be passed into the source code
bytes[] bytesArgs; // ════════════════╸ Bytes arguments that will be passed into the source code
}
error EmptySource();
error EmptySecrets();
error EmptyArgs();
error NoInlineSecrets();
/// @notice Encodes a Request to CBOR encoded bytes
/// @param self The request to encode
/// @return CBOR encoded bytes
function encodeCBOR(Request memory self) internal pure returns (bytes memory) {
CBOR.CBORBuffer memory buffer = CBOR.create(DEFAULT_BUFFER_SIZE);
buffer.writeString("codeLocation");
buffer.writeUInt256(uint256(self.codeLocation));
buffer.writeString("language");
buffer.writeUInt256(uint256(self.language));
buffer.writeString("source");
buffer.writeString(self.source);
if (self.args.length > 0) {
buffer.writeString("args");
buffer.startArray();
for (uint256 i = 0; i < self.args.length; ++i) {
buffer.writeString(self.args[i]);
}
buffer.endSequence();
}
if (self.encryptedSecretsReference.length > 0) {
if (self.secretsLocation == Location.Inline) {
revert NoInlineSecrets();
}
buffer.writeString("secretsLocation");
buffer.writeUInt256(uint256(self.secretsLocation));
buffer.writeString("secrets");
buffer.writeBytes(self.encryptedSecretsReference);
}
if (self.bytesArgs.length > 0) {
buffer.writeString("bytesArgs");
buffer.startArray();
for (uint256 i = 0; i < self.bytesArgs.length; ++i) {
buffer.writeBytes(self.bytesArgs[i]);
}
buffer.endSequence();
}
return buffer.buf.buf;
}
/// @notice Initializes a Chainlink Functions Request
/// @dev Sets the codeLocation and code on the request
/// @param self The uninitialized request
/// @param codeLocation The user provided source code location
/// @param language The programming language of the user code
/// @param source The user provided source code or a url
function initializeRequest(
Request memory self,
Location codeLocation,
CodeLanguage language,
string memory source
) internal pure {
if (bytes(source).length == 0) revert EmptySource();
self.codeLocation = codeLocation;
self.language = language;
self.source = source;
}
/// @notice Initializes a Chainlink Functions Request
/// @dev Simplified version of initializeRequest for PoC
/// @param self The uninitialized request
/// @param javaScriptSource The user provided JS code (must not be empty)
function initializeRequestForInlineJavaScript(Request memory self, string memory javaScriptSource) internal pure {
initializeRequest(self, Location.Inline, CodeLanguage.JavaScript, javaScriptSource);
}
/// @notice Adds Remote user encrypted secrets to a Request
/// @param self The initialized request
/// @param encryptedSecretsReference Encrypted comma-separated string of URLs pointing to off-chain secrets
function addSecretsReference(Request memory self, bytes memory encryptedSecretsReference) internal pure {
if (encryptedSecretsReference.length == 0) revert EmptySecrets();
self.secretsLocation = Location.Remote;
self.encryptedSecretsReference = encryptedSecretsReference;
}
/// @notice Adds DON-hosted secrets reference to a Request
/// @param self The initialized request
/// @param slotID Slot ID of the user's secrets hosted on DON
/// @param version User data version (for the slotID)
function addDONHostedSecrets(Request memory self, uint8 slotID, uint64 version) internal pure {
CBOR.CBORBuffer memory buffer = CBOR.create(DEFAULT_BUFFER_SIZE);
buffer.writeString("slotID");
buffer.writeUInt64(slotID);
buffer.writeString("version");
buffer.writeUInt64(version);
self.secretsLocation = Location.DONHosted;
self.encryptedSecretsReference = buffer.buf.buf;
}
/// @notice Sets args for the user run function
/// @param self The initialized request
/// @param args The array of string args (must not be empty)
function setArgs(Request memory self, string[] memory args) internal pure {
if (args.length == 0) revert EmptyArgs();
self.args = args;
}
/// @notice Sets bytes args for the user run function
/// @param self The initialized request
/// @param args The array of bytes args (must not be empty)
function setBytesArgs(Request memory self, bytes[] memory args) internal pure {
if (args.length == 0) revert EmptyArgs();
self.bytesArgs = args;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import {IFunctionsSubscriptions} from "../interfaces/IFunctionsSubscriptions.sol";
/// @title Library of types that are used for fulfillment of a Functions request
library FunctionsResponse {
// Used to send request information from the Router to the Coordinator
struct RequestMeta {
bytes data; // ══════════════════╸ CBOR encoded Chainlink Functions request data, use FunctionsRequest library to encode a request
bytes32 flags; // ═══════════════╸ Per-subscription flags
address requestingContract; // ══╗ The client contract that is sending the request
uint96 availableBalance; // ═════╝ Common LINK balance of the subscription that is controlled by the Router to be used for all consumer requests.
uint72 adminFee; // ═════════════╗ Flat fee (in Juels of LINK) that will be paid to the Router Owner for operation of the network
uint64 subscriptionId; // ║ Identifier of the billing subscription that will be charged for the request
uint64 initiatedRequests; // ║ The number of requests that have been started
uint32 callbackGasLimit; // ║ The amount of gas that the callback to the consuming contract will be given
uint16 dataVersion; // ══════════╝ The version of the structure of the CBOR encoded request data
uint64 completedRequests; // ════╗ The number of requests that have successfully completed or timed out
address subscriptionOwner; // ═══╝ The owner of the billing subscription
}
enum FulfillResult {
FULFILLED, // 0
USER_CALLBACK_ERROR, // 1
INVALID_REQUEST_ID, // 2
COST_EXCEEDS_COMMITMENT, // 3
INSUFFICIENT_GAS_PROVIDED, // 4
SUBSCRIPTION_BALANCE_INVARIANT_VIOLATION, // 5
INVALID_COMMITMENT // 6
}
struct Commitment {
bytes32 requestId; // ═════════════════╸ A unique identifier for a Chainlink Functions request
address coordinator; // ═══════════════╗ The Coordinator contract that manages the DON that is servicing a request
uint96 estimatedTotalCostJuels; // ════╝ The maximum cost in Juels (1e18) of LINK that will be charged to fulfill a request
address client; // ════════════════════╗ The client contract that sent the request
uint64 subscriptionId; // ║ Identifier of the billing subscription that will be charged for the request
uint32 callbackGasLimit; // ═══════════╝ The amount of gas that the callback to the consuming contract will be given
uint72 adminFee; // ═══════════════════╗ Flat fee (in Juels of LINK) that will be paid to the Router Owner for operation of the network
uint72 donFee; // ║ Fee (in Juels of LINK) that will be split between Node Operators for servicing a request
uint40 gasOverheadBeforeCallback; // ║ Represents the average gas execution cost before the fulfillment callback.
uint40 gasOverheadAfterCallback; // ║ Represents the average gas execution cost after the fulfillment callback.
uint32 timeoutTimestamp; // ═══════════╝ The timestamp at which a request will be eligible to be timed out
}
}// SPDX-License-Identifier: BSD-2-Clause
pragma solidity ^0.8.4;
/**
* @dev A library for working with mutable byte buffers in Solidity.
*
* Byte buffers are mutable and expandable, and provide a variety of primitives
* for appending to them. At any time you can fetch a bytes object containing the
* current contents of the buffer. The bytes object should not be stored between
* operations, as it may change due to resizing of the buffer.
*/
library Buffer {
/**
* @dev Represents a mutable buffer. Buffers have a current value (buf) and
* a capacity. The capacity may be longer than the current value, in
* which case it can be extended without the need to allocate more memory.
*/
struct buffer {
bytes buf;
uint capacity;
}
/**
* @dev Initializes a buffer with an initial capacity.
* @param buf The buffer to initialize.
* @param capacity The number of bytes of space to allocate the buffer.
* @return The buffer, for chaining.
*/
function init(buffer memory buf, uint capacity) internal pure returns(buffer memory) {
if (capacity % 32 != 0) {
capacity += 32 - (capacity % 32);
}
// Allocate space for the buffer data
buf.capacity = capacity;
assembly {
let ptr := mload(0x40)
mstore(buf, ptr)
mstore(ptr, 0)
let fpm := add(32, add(ptr, capacity))
if lt(fpm, ptr) {
revert(0, 0)
}
mstore(0x40, fpm)
}
return buf;
}
/**
* @dev Initializes a new buffer from an existing bytes object.
* Changes to the buffer may mutate the original value.
* @param b The bytes object to initialize the buffer with.
* @return A new buffer.
*/
function fromBytes(bytes memory b) internal pure returns(buffer memory) {
buffer memory buf;
buf.buf = b;
buf.capacity = b.length;
return buf;
}
function resize(buffer memory buf, uint capacity) private pure {
bytes memory oldbuf = buf.buf;
init(buf, capacity);
append(buf, oldbuf);
}
/**
* @dev Sets buffer length to 0.
* @param buf The buffer to truncate.
* @return The original buffer, for chaining..
*/
function truncate(buffer memory buf) internal pure returns (buffer memory) {
assembly {
let bufptr := mload(buf)
mstore(bufptr, 0)
}
return buf;
}
/**
* @dev Appends len bytes of a byte string to a buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @param len The number of bytes to copy.
* @return The original buffer, for chaining.
*/
function append(buffer memory buf, bytes memory data, uint len) internal pure returns(buffer memory) {
require(len <= data.length);
uint off = buf.buf.length;
uint newCapacity = off + len;
if (newCapacity > buf.capacity) {
resize(buf, newCapacity * 2);
}
uint dest;
uint src;
assembly {
// Memory address of the buffer data
let bufptr := mload(buf)
// Length of existing buffer data
let buflen := mload(bufptr)
// Start address = buffer address + offset + sizeof(buffer length)
dest := add(add(bufptr, 32), off)
// Update buffer length if we're extending it
if gt(newCapacity, buflen) {
mstore(bufptr, newCapacity)
}
src := add(data, 32)
}
// Copy word-length chunks while possible
for (; len >= 32; len -= 32) {
assembly {
mstore(dest, mload(src))
}
dest += 32;
src += 32;
}
// Copy remaining bytes
unchecked {
uint mask = (256 ** (32 - len)) - 1;
assembly {
let srcpart := and(mload(src), not(mask))
let destpart := and(mload(dest), mask)
mstore(dest, or(destpart, srcpart))
}
}
return buf;
}
/**
* @dev Appends a byte string to a buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chaining.
*/
function append(buffer memory buf, bytes memory data) internal pure returns (buffer memory) {
return append(buf, data, data.length);
}
/**
* @dev Appends a byte to the buffer. Resizes if doing so would exceed the
* capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chaining.
*/
function appendUint8(buffer memory buf, uint8 data) internal pure returns(buffer memory) {
uint off = buf.buf.length;
uint offPlusOne = off + 1;
if (off >= buf.capacity) {
resize(buf, offPlusOne * 2);
}
assembly {
// Memory address of the buffer data
let bufptr := mload(buf)
// Address = buffer address + sizeof(buffer length) + off
let dest := add(add(bufptr, off), 32)
mstore8(dest, data)
// Update buffer length if we extended it
if gt(offPlusOne, mload(bufptr)) {
mstore(bufptr, offPlusOne)
}
}
return buf;
}
/**
* @dev Appends len bytes of bytes32 to a buffer. Resizes if doing so would
* exceed the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @param len The number of bytes to write (left-aligned).
* @return The original buffer, for chaining.
*/
function append(buffer memory buf, bytes32 data, uint len) private pure returns(buffer memory) {
uint off = buf.buf.length;
uint newCapacity = len + off;
if (newCapacity > buf.capacity) {
resize(buf, newCapacity * 2);
}
unchecked {
uint mask = (256 ** len) - 1;
// Right-align data
data = data >> (8 * (32 - len));
assembly {
// Memory address of the buffer data
let bufptr := mload(buf)
// Address = buffer address + sizeof(buffer length) + newCapacity
let dest := add(bufptr, newCapacity)
mstore(dest, or(and(mload(dest), not(mask)), data))
// Update buffer length if we extended it
if gt(newCapacity, mload(bufptr)) {
mstore(bufptr, newCapacity)
}
}
}
return buf;
}
/**
* @dev Appends a bytes20 to the buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chhaining.
*/
function appendBytes20(buffer memory buf, bytes20 data) internal pure returns (buffer memory) {
return append(buf, bytes32(data), 20);
}
/**
* @dev Appends a bytes32 to the buffer. Resizes if doing so would exceed
* the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @return The original buffer, for chaining.
*/
function appendBytes32(buffer memory buf, bytes32 data) internal pure returns (buffer memory) {
return append(buf, data, 32);
}
/**
* @dev Appends a byte to the end of the buffer. Resizes if doing so would
* exceed the capacity of the buffer.
* @param buf The buffer to append to.
* @param data The data to append.
* @param len The number of bytes to write (right-aligned).
* @return The original buffer.
*/
function appendInt(buffer memory buf, uint data, uint len) internal pure returns(buffer memory) {
uint off = buf.buf.length;
uint newCapacity = len + off;
if (newCapacity > buf.capacity) {
resize(buf, newCapacity * 2);
}
uint mask = (256 ** len) - 1;
assembly {
// Memory address of the buffer data
let bufptr := mload(buf)
// Address = buffer address + sizeof(buffer length) + newCapacity
let dest := add(bufptr, newCapacity)
mstore(dest, or(and(mload(dest), not(mask)), data))
// Update buffer length if we extended it
if gt(newCapacity, mload(bufptr)) {
mstore(bufptr, newCapacity)
}
}
return buf;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "../../@ensdomains/buffer/v0.1.0/Buffer.sol";
/**
* @dev A library for populating CBOR encoded payload in Solidity.
*
* https://datatracker.ietf.org/doc/html/rfc7049
*
* The library offers various write* and start* methods to encode values of different types.
* The resulted buffer can be obtained with data() method.
* Encoding of primitive types is staightforward, whereas encoding of sequences can result
* in an invalid CBOR if start/write/end flow is violated.
* For the purpose of gas saving, the library does not verify start/write/end flow internally,
* except for nested start/end pairs.
*/
library CBOR {
using Buffer for Buffer.buffer;
struct CBORBuffer {
Buffer.buffer buf;
uint256 depth;
}
uint8 private constant MAJOR_TYPE_INT = 0;
uint8 private constant MAJOR_TYPE_NEGATIVE_INT = 1;
uint8 private constant MAJOR_TYPE_BYTES = 2;
uint8 private constant MAJOR_TYPE_STRING = 3;
uint8 private constant MAJOR_TYPE_ARRAY = 4;
uint8 private constant MAJOR_TYPE_MAP = 5;
uint8 private constant MAJOR_TYPE_TAG = 6;
uint8 private constant MAJOR_TYPE_CONTENT_FREE = 7;
uint8 private constant TAG_TYPE_BIGNUM = 2;
uint8 private constant TAG_TYPE_NEGATIVE_BIGNUM = 3;
uint8 private constant CBOR_FALSE = 20;
uint8 private constant CBOR_TRUE = 21;
uint8 private constant CBOR_NULL = 22;
uint8 private constant CBOR_UNDEFINED = 23;
function create(uint256 capacity) internal pure returns(CBORBuffer memory cbor) {
Buffer.init(cbor.buf, capacity);
cbor.depth = 0;
return cbor;
}
function data(CBORBuffer memory buf) internal pure returns(bytes memory) {
require(buf.depth == 0, "Invalid CBOR");
return buf.buf.buf;
}
function writeUInt256(CBORBuffer memory buf, uint256 value) internal pure {
buf.buf.appendUint8(uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_BIGNUM));
writeBytes(buf, abi.encode(value));
}
function writeInt256(CBORBuffer memory buf, int256 value) internal pure {
if (value < 0) {
buf.buf.appendUint8(
uint8((MAJOR_TYPE_TAG << 5) | TAG_TYPE_NEGATIVE_BIGNUM)
);
writeBytes(buf, abi.encode(uint256(-1 - value)));
} else {
writeUInt256(buf, uint256(value));
}
}
function writeUInt64(CBORBuffer memory buf, uint64 value) internal pure {
writeFixedNumeric(buf, MAJOR_TYPE_INT, value);
}
function writeInt64(CBORBuffer memory buf, int64 value) internal pure {
if(value >= 0) {
writeFixedNumeric(buf, MAJOR_TYPE_INT, uint64(value));
} else{
writeFixedNumeric(buf, MAJOR_TYPE_NEGATIVE_INT, uint64(-1 - value));
}
}
function writeBytes(CBORBuffer memory buf, bytes memory value) internal pure {
writeFixedNumeric(buf, MAJOR_TYPE_BYTES, uint64(value.length));
buf.buf.append(value);
}
function writeString(CBORBuffer memory buf, string memory value) internal pure {
writeFixedNumeric(buf, MAJOR_TYPE_STRING, uint64(bytes(value).length));
buf.buf.append(bytes(value));
}
function writeBool(CBORBuffer memory buf, bool value) internal pure {
writeContentFree(buf, value ? CBOR_TRUE : CBOR_FALSE);
}
function writeNull(CBORBuffer memory buf) internal pure {
writeContentFree(buf, CBOR_NULL);
}
function writeUndefined(CBORBuffer memory buf) internal pure {
writeContentFree(buf, CBOR_UNDEFINED);
}
function startArray(CBORBuffer memory buf) internal pure {
writeIndefiniteLengthType(buf, MAJOR_TYPE_ARRAY);
buf.depth += 1;
}
function startFixedArray(CBORBuffer memory buf, uint64 length) internal pure {
writeDefiniteLengthType(buf, MAJOR_TYPE_ARRAY, length);
}
function startMap(CBORBuffer memory buf) internal pure {
writeIndefiniteLengthType(buf, MAJOR_TYPE_MAP);
buf.depth += 1;
}
function startFixedMap(CBORBuffer memory buf, uint64 length) internal pure {
writeDefiniteLengthType(buf, MAJOR_TYPE_MAP, length);
}
function endSequence(CBORBuffer memory buf) internal pure {
writeIndefiniteLengthType(buf, MAJOR_TYPE_CONTENT_FREE);
buf.depth -= 1;
}
function writeKVString(CBORBuffer memory buf, string memory key, string memory value) internal pure {
writeString(buf, key);
writeString(buf, value);
}
function writeKVBytes(CBORBuffer memory buf, string memory key, bytes memory value) internal pure {
writeString(buf, key);
writeBytes(buf, value);
}
function writeKVUInt256(CBORBuffer memory buf, string memory key, uint256 value) internal pure {
writeString(buf, key);
writeUInt256(buf, value);
}
function writeKVInt256(CBORBuffer memory buf, string memory key, int256 value) internal pure {
writeString(buf, key);
writeInt256(buf, value);
}
function writeKVUInt64(CBORBuffer memory buf, string memory key, uint64 value) internal pure {
writeString(buf, key);
writeUInt64(buf, value);
}
function writeKVInt64(CBORBuffer memory buf, string memory key, int64 value) internal pure {
writeString(buf, key);
writeInt64(buf, value);
}
function writeKVBool(CBORBuffer memory buf, string memory key, bool value) internal pure {
writeString(buf, key);
writeBool(buf, value);
}
function writeKVNull(CBORBuffer memory buf, string memory key) internal pure {
writeString(buf, key);
writeNull(buf);
}
function writeKVUndefined(CBORBuffer memory buf, string memory key) internal pure {
writeString(buf, key);
writeUndefined(buf);
}
function writeKVMap(CBORBuffer memory buf, string memory key) internal pure {
writeString(buf, key);
startMap(buf);
}
function writeKVArray(CBORBuffer memory buf, string memory key) internal pure {
writeString(buf, key);
startArray(buf);
}
function writeFixedNumeric(
CBORBuffer memory buf,
uint8 major,
uint64 value
) private pure {
if (value <= 23) {
buf.buf.appendUint8(uint8((major << 5) | value));
} else if (value <= 0xFF) {
buf.buf.appendUint8(uint8((major << 5) | 24));
buf.buf.appendInt(value, 1);
} else if (value <= 0xFFFF) {
buf.buf.appendUint8(uint8((major << 5) | 25));
buf.buf.appendInt(value, 2);
} else if (value <= 0xFFFFFFFF) {
buf.buf.appendUint8(uint8((major << 5) | 26));
buf.buf.appendInt(value, 4);
} else {
buf.buf.appendUint8(uint8((major << 5) | 27));
buf.buf.appendInt(value, 8);
}
}
function writeIndefiniteLengthType(CBORBuffer memory buf, uint8 major)
private
pure
{
buf.buf.appendUint8(uint8((major << 5) | 31));
}
function writeDefiniteLengthType(CBORBuffer memory buf, uint8 major, uint64 length)
private
pure
{
writeFixedNumeric(buf, major, length);
}
function writeContentFree(CBORBuffer memory buf, uint8 value) private pure {
buf.buf.appendUint8(uint8((MAJOR_TYPE_CONTENT_FREE << 5) | value));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
/**
* @title IProviderStorage
* @dev Interface defining the provider storage functionality
*/
interface IProviderStorage {
struct Provider {
string source;
bool isRegistered;
uint256 registeredAt;
uint256 lastUpdated;
uint256 useCount;
}
event ProviderRegistered(bytes32 indexed providerHash);
event ProviderUpdated(bytes32 indexed providerHash);
event ProviderUnregistered(bytes32 indexed providerHash);
function registerSourceProvider(string calldata source) external;
function updateSourceProvider(bytes32 providerHash, string calldata newSource) external;
function unregisterSourceProvider(bytes32 providerHash) external;
function getProvider(bytes32 providerHash) external view returns (
string memory source,
bool isRegistered,
uint256 registeredAt,
uint256 lastUpdated,
uint256 useCount
);
function isProviderRegistered(string calldata source) external view returns (bool);
function incrementProviderUseCount(bytes32 providerHash) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "../interfaces/IProviderStorage.sol";
/**
* @title AbstractProviderStorage
* @dev Abstract contract implementing provider storage functionality
*/
abstract contract AbstractProviderStorage is IProviderStorage, Ownable {
mapping(bytes32 => Provider) private _providers;
bytes32[] private _providerHashes;
modifier onlyRegistered(bytes32 providerHash) {
require(_providers[providerHash].isRegistered, "Provider not registered");
_;
}
modifier notRegistered(bytes32 providerHash) {
require(!_providers[providerHash].isRegistered, "Provider already registered");
_;
}
function registerSourceProvider(
string calldata source
) external override onlyOwner {
bytes32 hash = keccak256(abi.encodePacked(source));
require(!_providers[hash].isRegistered, "Provider already registered");
_providers[hash] = Provider({
source: source,
isRegistered: true,
registeredAt: block.timestamp,
lastUpdated: block.timestamp,
useCount: 0
});
_providerHashes.push(hash);
emit ProviderRegistered(hash);
}
function updateSourceProvider(
bytes32 providerHash,
string calldata newSource
) external override onlyOwner onlyRegistered(providerHash) {
Provider storage provider = _providers[providerHash];
provider.source = newSource;
provider.lastUpdated = block.timestamp;
emit ProviderUpdated(providerHash);
}
function unregisterSourceProvider(
bytes32 providerHash
) external override onlyOwner onlyRegistered(providerHash) {
_providers[providerHash].isRegistered = false;
emit ProviderUnregistered(providerHash);
}
function getProvider(
bytes32 providerHash
) external view override returns (
string memory source,
bool isRegistered,
uint256 registeredAt,
uint256 lastUpdated,
uint256 useCount
) {
Provider memory provider = _providers[providerHash];
return (
provider.source,
provider.isRegistered,
provider.registeredAt,
provider.lastUpdated,
provider.useCount
);
}
function getProviderSource(
bytes32 providerHash
) internal view returns (string memory) {
require(_providers[providerHash].isRegistered, "Provider not registered");
return _providers[providerHash].source;
}
function isProviderRegistered(
string calldata source
) external view override returns (bool) {
bytes32 hash = keccak256(abi.encodePacked(source));
return _providers[hash].isRegistered;
}
function incrementProviderUseCount(
bytes32 providerHash
) external override onlyRegistered(providerHash) {
_providers[providerHash].useCount++;
}
function getProviderCount() public view returns (uint256) {
return _providerHashes.length;
}
function getProviderHashAt(uint256 index) public view returns (bytes32) {
require(index < _providerHashes.length, "Index out of bounds");
return _providerHashes[index];
}
}{
"optimizer": {
"enabled": true,
"runs": 100000
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract ABI
API[{"inputs":[{"internalType":"address","name":"router","type":"address"},{"internalType":"bytes32","name":"_donId","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EmptyArgs","type":"error"},{"inputs":[],"name":"EmptySource","type":"error"},{"inputs":[],"name":"NoInlineSecrets","type":"error"},{"inputs":[],"name":"OnlyRouterCanFulfill","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"UnauthorizedContract","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contractAddress","type":"address"}],"name":"ContractAuthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"contractAddress","type":"address"}],"name":"ContractDeauthorized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"response","type":"bytes"}],"name":"OCRResponse","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"providerHash","type":"bytes32"}],"name":"ProviderRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"providerHash","type":"bytes32"}],"name":"ProviderUnregistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"providerHash","type":"bytes32"}],"name":"ProviderUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"requestId","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"err","type":"bytes"}],"name":"RequestFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"RequestFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"RequestSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"data","type":"string"}],"name":"RequestSent","type":"event"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"authorizeContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorizedContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"callbackGasLimit","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"deauthorizeContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"donId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"encryptedSecretsReference","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"providerHash","type":"bytes32"}],"name":"getProvider","outputs":[{"internalType":"string","name":"source","type":"string"},{"internalType":"bool","name":"isRegistered","type":"bool"},{"internalType":"uint256","name":"registeredAt","type":"uint256"},{"internalType":"uint256","name":"lastUpdated","type":"uint256"},{"internalType":"uint256","name":"useCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProviderCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getProviderHashAt","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"bytes","name":"response","type":"bytes"},{"internalType":"bytes","name":"err","type":"bytes"}],"name":"handleOracleFulfillment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"providerHash","type":"bytes32"}],"name":"incrementProviderUseCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"isContractAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"source","type":"string"}],"name":"isProviderRegistered","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":"string","name":"source","type":"string"}],"name":"registerSourceProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes32","name":"providerHash","type":"bytes32"}],"name":"requestComputation","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"requestToRequester","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"secretsLocation","outputs":[{"internalType":"enum FunctionsRequest.Location","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_subscriptionId","type":"uint64"},{"internalType":"uint32","name":"_callbackGasLimit","type":"uint32"},{"internalType":"enum FunctionsRequest.Location","name":"_secretsLocation","type":"uint8"},{"internalType":"bytes","name":"_encryptedSecretsReference","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"subscriptionId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"providerHash","type":"bytes32"}],"name":"unregisterSourceProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"providerHash","type":"bytes32"},{"internalType":"string","name":"newSource","type":"string"}],"name":"updateSourceProvider","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523480156200001157600080fd5b5060405162002c6c38038062002c6c8339810160408190526200003491620000f6565b8133806200005d57604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6200006881620000a6565b506001600160a01b03166080526001600355336200009c57604051631e4fbdf760e01b815233600482015260240162000054565b6004555062000132565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600080604083850312156200010a57600080fd5b82516001600160a01b03811681146200012257600080fd5b6020939093015192949293505050565b608051612b17620001556000396000818161046d0152611af80152612b176000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c80636e861c0e116100e3578063b9bdccf31161008c578063d5b9221b11610066578063d5b9221b1461040c578063e93ce74f1461042f578063f2fde38b1461044257600080fd5b8063b9bdccf3146103d1578063bf8a793f146103e4578063cdc634f1146103f757600080fd5b80638da5cb5b116100bd5780638da5cb5b146103975780638dbe7b9d146103b5578063abb08b3f146103be57600080fd5b80636e861c0e14610369578063715018a61461037c57806388405e6c1461038457600080fd5b806333c0950a1161014557806346ce41751161011f57806346ce41751461033b578063603ea4981461034357806367561d931461035657600080fd5b806333c0950a146102a95780633f66286a146102cd57806345e1fa0d1461032857600080fd5b8063103aeda711610176578063103aeda71461020e57806324f74697146102575780632f73bab81461028857600080fd5b806309c1ba2e1461019d5780630ca76175146101cf5780630e599a73146101e4575b600080fd5b6005546101b19067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b6101e26101dd366004612171565b610455565b005b600554610201906c01000000000000000000000000900460ff1681565b6040516101c6919061220d565b61024761021c36600461224e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205460ff1690565b60405190151581526020016101c6565b6005546102739068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016101c6565b61029b610296366004612284565b6104ff565b6040519081526020016101c6565b6102bc6102b7366004612284565b610597565b6040516101c695949392919061230b565b6103036102db366004612284565b60076020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c6565b6101e261033636600461238b565b6106b9565b60025461029b565b6101e26103513660046123cd565b6108c2565b6101e261036436600461224e565b610985565b6101e261037736600461224e565b610a16565b6101e2610aa1565b61024761039236600461238b565b610ab5565b60005473ffffffffffffffffffffffffffffffffffffffff16610303565b61029b60045481565b6101e26103cc366004612463565b610b1c565b61029b6103df3660046124af565b610bf5565b6101e26103f2366004612284565b610f45565b6103ff61102f565b6040516101c691906124fb565b61024761041a36600461224e565b60086020526000908152604090205460ff1681565b6101e261043d366004612284565b6110bd565b6101e261045036600461224e565b611161565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146104c4576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104cf8383836111c2565b60405183907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a2505050565b6002546000908210610572576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496e646578206f7574206f6620626f756e64730000000000000000000000000060448201526064015b60405180910390fd5b600282815481106105855761058561250e565b90600052602060002001549050919050565b60606000806000806000600160008881526020019081526020016000206040518060a00160405290816000820180546105cf9061253d565b80601f01602080910402602001604051908101604052809291908181526020018280546105fb9061253d565b80156106485780601f1061061d57610100808354040283529160200191610648565b820191906000526020600020905b81548152906001019060200180831161062b57829003601f168201915b505050505081526020016001820160009054906101000a900460ff161515151581526020016002820154815260200160038201548152602001600482015481525050905080600001518160200151826040015183606001518460800151955095509550955095505091939590929450565b6106c1611472565b600082826040516020016106d6929190612590565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600193849052919091209091015490915060ff161561078c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f50726f766964657220616c7265616479207265676973746572656400000000006044820152606401610569565b6040518060a0016040528084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250938552505060016020808501829052426040808701829052606087019190915260809095018490528684525250208151819061080590826125ee565b506020820151600182810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001692151592909217909155604080840151600280850191909155606085015160038501556080909401516004909301929092558254908101835560009283527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018390555182917f32dfc590cafade73cbba6680180fc790a94eb0cfa92a3186559d6fb8864101dd91a2505050565b6108ca6114c5565b6108d2611472565b6005805463ffffffff861668010000000000000000027fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911667ffffffffffffffff881617178082558491907fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff166c01000000000000000000000000836002811115610961576109616121de565b02179055506006610973828483612708565b5061097e6001600355565b5050505050565b61098d6114c5565b610995611472565b73ffffffffffffffffffffffffffffffffffffffff811660008181526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f8983a1f3c3cb45c24c8226b5b805e3b6eb49686530b808534b2a920129eff6519190a2610a136001600355565b50565b610a1e6114c5565b610a26611472565b73ffffffffffffffffffffffffffffffffffffffff811660008181526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f54142b7cb3ceaa9e564243ce4cc2303723c842a1144192de6b3c594f68b16a9a9190a2610a136001600355565b610aa9611472565b610ab36000611508565b565b6000808383604051602001610acb929190612590565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815260019283905220015460ff169150505b92915050565b610b24611472565b60008381526001602081905260409091200154839060ff16610ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f50726f7669646572206e6f7420726567697374657265640000000000000000006044820152606401610569565b600084815260016020526040902080610bbc848683612708565b5042600382015560405185907f04ed8331e86b605a92965a0cf623cd7bf9a5cd75ca23c4a139245bca110b59f390600090a25050505050565b6000610bff6114c5565b3360009081526008602052604090205460ff16610c4a576040517fe195aa13000000000000000000000000000000000000000000000000000000008152336004820152602401610569565b6000610c558361157d565b9050610c986040805160e0810190915280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b610ca5816000808561169a565b60055460208201906c01000000000000000000000000900460ff166002811115610cd157610cd16121de565b90816002811115610ce457610ce46121de565b90525060068054610cf49061253d565b80601f0160208091040260200160405190810160405280929190818152602001828054610d209061253d565b8015610d6d5780601f10610d4257610100808354040283529160200191610d6d565b820191906000526020600020905b815481529060010190602001808311610d5057829003601f168201915b50505050506080820152604080516001808252818301909252600091816020015b6060815260200190600190039081610d8e57905050905086868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250855186945090925015159050610def57610def61250e565b6020908102919091010152610e048282611731565b6000610e3c610e1284611774565b60055460045467ffffffffffffffff82169168010000000000000000900463ffffffff1690611af3565b6040517fe93ce74f00000000000000000000000000000000000000000000000000000000815260048101889052909150309063e93ce74f90602401600060405180830381600087803b158015610e9157600080fd5b505af1158015610ea5573d6000803e3d6000fd5b505050600082815260076020526040812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905583517f7843201bc61dabd0c5d1ae50c3c5f42890f52e0e4499eb70174606c2b6686dab9250849190610f1257610f1261250e565b6020026020010151604051610f2791906124fb565b60405180910390a19350505050610f3e6001600355565b9392505050565b610f4d611472565b60008181526001602081905260409091200154819060ff16610fcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f50726f7669646572206e6f7420726567697374657265640000000000000000006044820152606401610569565b600082815260016020819052604080832090910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555183917fd1983ea33649b47070f29135589ec31ac5dc7eab4e3882668d50929807b6f68691a25050565b6006805461103c9061253d565b80601f01602080910402602001604051908101604052809291908181526020018280546110689061253d565b80156110b55780601f1061108a576101008083540402835291602001916110b5565b820191906000526020600020905b81548152906001019060200180831161109857829003601f168201915b505050505081565b60008181526001602081905260409091200154819060ff1661113b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f50726f7669646572206e6f7420726567697374657265640000000000000000006044820152606401610569565b600082815260016020526040812060040180549161115883612851565b91905055505050565b611169611472565b73ffffffffffffffffffffffffffffffffffffffff81166111b9576040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260006004820152602401610569565b610a1381611508565b6111ca6114c5565b60008381526007602052604090205473ffffffffffffffffffffffffffffffffffffffff1680611256576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e76616c6964207265717565737420494400000000000000000000000000006044820152606401610569565b81511561129a57837f61982c98cbc49d11759a948f460b92bca26bdf12ceee12c310f117eb2ca9a9cb8360405161128d91906124fb565b60405180910390a26112d3565b837f1f4509cd59b6c74633bed4200a8e35803ebaa37d5d0e229640ed5fce1200b053846040516112ca91906124fb565b60405180910390a25b60008481526007602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555173ffffffffffffffffffffffffffffffffffffffff83169061133390879087908790602401612889565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe3afe37200000000000000000000000000000000000000000000000000000000179052516113b491906128be565b6000604051808303816000865af19150503d80600081146113f1576040519150601f19603f3d011682016040523d82523d6000602084013e6113f6565b606091505b5050905080611461576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f43616c6c6261636b206661696c656400000000000000000000000000000000006044820152606401610569565b505061146d6001600355565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ab3576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610569565b600260035403611501576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600355565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000818152600160208190526040909120015460609060ff166115fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f50726f7669646572206e6f7420726567697374657265640000000000000000006044820152606401610569565b600082815260016020526040902080546116159061253d565b80601f01602080910402602001604051908101604052809291908181526020018280546116419061253d565b801561168e5780601f106116635761010080835404028352916020019161168e565b820191906000526020600020905b81548152906001019060200180831161167157829003601f168201915b50505050509050919050565b80516000036116d5576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838360028111156116e8576116e86121de565b908160028111156116fb576116fb6121de565b90525060408401828015611711576117116121de565b90818015611721576117216121de565b9052506060909301929092525050565b805160000361176c576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a090910152565b60606000611783610100611bd2565b90506117cd6040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082611bf390919063ffffffff16565b82516117eb9060028111156117e4576117e46121de565b8290611c0c565b60408051808201909152600881527f6c616e6775616765000000000000000000000000000000000000000000000000602082015261182a908290611bf3565b60408301516118419080156117e4576117e46121de565b60408051808201909152600681527f736f7572636500000000000000000000000000000000000000000000000000006020820152611880908290611bf3565b6060830151611890908290611bf3565b60a0830151511561193d5760408051808201909152600481527f617267730000000000000000000000000000000000000000000000000000000060208201526118da908290611bf3565b6118e381611c49565b60005b8360a0015151811015611933576119238460a00151828151811061190c5761190c61250e565b602002602001015183611bf390919063ffffffff16565b61192c81612851565b90506118e6565b5061193d81611c6d565b60808301515115611a3e57600083602001516002811115611960576119606121de565b03611997576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e000000000000000000000000000000000060208201526119d6908290611bf3565b6119ef836020015160028111156117e4576117e46121de565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152611a2e908290611bf3565b6080830151611a3e908290611c8b565b60c08301515115611aeb5760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152611a88908290611bf3565b611a9181611c49565b60005b8360c0015151811015611ae157611ad18460c001518281518110611aba57611aba61250e565b602002602001015183611c8b90919063ffffffff16565b611ada81612851565b9050611a94565b50611aeb81611c6d565b515192915050565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401611b589594939291906128da565b6020604051808303816000875af1158015611b77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9b9190612924565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b611bda612062565b8051611be69083611c98565b5060006020820152919050565b611c008260038351611d0f565b815161146d9082611e36565b8151611c199060c2611e57565b50611c458282604051602001611c3191815260200190565b604051602081830303815290604052611c8b565b5050565b611c54816004611ec0565b600181602001818151611c67919061293d565b90525050565b611c78816007611ec0565b600181602001818151611c679190612950565b611c008260028351611d0f565b604080518082019091526060815260006020820152611cb8602083612963565b15611ce057611cc8602083612963565b611cd3906020612950565b611cdd908361293d565b91505b602080840183905260405180855260008152908184010181811015611d0457600080fd5b604052509192915050565b60178167ffffffffffffffff1611611d3c578251611d369060e0600585901b168317611e57565b50505050565b60ff8167ffffffffffffffff1611611d7e578251611d65906018611fe0600586901b1617611e57565b508251611d369067ffffffffffffffff83166001611ed7565b61ffff8167ffffffffffffffff1611611dc1578251611da8906019611fe0600586901b1617611e57565b508251611d369067ffffffffffffffff83166002611ed7565b63ffffffff8167ffffffffffffffff1611611e06578251611ded90601a611fe0600586901b1617611e57565b508251611d369067ffffffffffffffff83166004611ed7565b8251611e1d90601b611fe0600586901b1617611e57565b508251611d369067ffffffffffffffff83166008611ed7565b604080518082019091526060815260006020820152610f3e83838451611f5c565b6040805180820190915260608152600060208201528251516000611e7c82600161293d565b905084602001518210611e9d57611e9d85611e9883600261299e565b61204b565b8451602083820101858153508051821115611eb6578181525b5093949350505050565b815161146d90601f611fe0600585901b1617611e57565b6040805180820190915260608152600060208201528351516000611efb828561293d565b90508560200151811115611f1857611f1886611e9883600261299e565b60006001611f2886610100612ad5565b611f329190612950565b90508651828101878319825116178152508051831115611f50578281525b50959695505050505050565b6040805180820190915260608152600060208201528251821115611f7f57600080fd5b8351516000611f8e848361293d565b90508560200151811115611fab57611fab86611e9883600261299e565b855180518382016020019160009180851115611fc5578482525b505050602086015b602086106120055780518252611fe460208361293d565b9150611ff160208261293d565b9050611ffe602087612950565b9550611fcd565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516120578383611c98565b50611d368382611e36565b604051806040016040528061208a604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126120d757600080fd5b813567ffffffffffffffff808211156120f2576120f2612097565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561213857612138612097565b8160405283815286602085880101111561215157600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561218657600080fd5b83359250602084013567ffffffffffffffff808211156121a557600080fd5b6121b1878388016120c6565b935060408601359150808211156121c757600080fd5b506121d4868287016120c6565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612248577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60006020828403121561226057600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f3e57600080fd5b60006020828403121561229657600080fd5b5035919050565b60005b838110156122b85781810151838201526020016122a0565b50506000910152565b600081518084526122d981602086016020860161229d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60a08152600061231e60a08301886122c1565b95151560208301525060408101939093526060830191909152608090910152919050565b60008083601f84011261235457600080fd5b50813567ffffffffffffffff81111561236c57600080fd5b60208301915083602082850101111561238457600080fd5b9250929050565b6000806020838503121561239e57600080fd5b823567ffffffffffffffff8111156123b557600080fd5b6123c185828601612342565b90969095509350505050565b6000806000806000608086880312156123e557600080fd5b853567ffffffffffffffff80821682146123fe57600080fd5b90955060208701359063ffffffff8216821461241957600080fd5b9094506040870135906003821061242f57600080fd5b9093506060870135908082111561244557600080fd5b5061245288828901612342565b969995985093965092949392505050565b60008060006040848603121561247857600080fd5b83359250602084013567ffffffffffffffff81111561249657600080fd5b6124a286828701612342565b9497909650939450505050565b6000806000604084860312156124c457600080fd5b833567ffffffffffffffff8111156124db57600080fd5b6124e786828701612342565b909790965060209590950135949350505050565b602081526000610f3e60208301846122c1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061255157607f821691505b60208210810361258a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183823760009101908152919050565b601f82111561146d57600081815260208120601f850160051c810160208610156125c75750805b601f850160051c820191505b818110156125e6578281556001016125d3565b505050505050565b815167ffffffffffffffff81111561260857612608612097565b61261c81612616845461253d565b846125a0565b602080601f83116001811461266f57600084156126395750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556125e6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156126bc5788860151825594840194600190910190840161269d565b50858210156126f857878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83111561272057612720612097565b6127348361272e835461253d565b836125a0565b6000601f84116001811461278657600085156127505750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561097e565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156127d557868501358255602094850194600190920191016127b5565b5086821015612810577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361288257612882612822565b5060010190565b8381526060602082015260006128a260608301856122c1565b82810360408401526128b481856122c1565b9695505050505050565b600082516128d081846020870161229d565b9190910192915050565b67ffffffffffffffff8616815260a0602082015260006128fd60a08301876122c1565b61ffff9590951660408301525063ffffffff92909216606083015260809091015292915050565b60006020828403121561293657600080fd5b5051919050565b80820180821115610b1657610b16612822565b81810381811115610b1657610b16612822565b600082612999577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b8082028115828204841417610b1657610b16612822565b600181815b80851115612a0e57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156129f4576129f4612822565b80851615612a0157918102915b93841c93908002906129ba565b509250929050565b600082612a2557506001610b16565b81612a3257506000610b16565b8160018114612a485760028114612a5257612a6e565b6001915050610b16565b60ff841115612a6357612a63612822565b50506001821b610b16565b5060208310610133831016604e8410600b8410161715612a91575081810a610b16565b612a9b83836129b5565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612acd57612acd612822565b029392505050565b6000610f3e8383612a1656fea2646970667358221220d8218751231908faa8e1bb856e6e1b36650ae0ebd312298aff50c3664356ec3664736f6c63430008140033000000000000000000000000f9b8fc078197181c841c296c876945aaa425b27866756e2d6176616c616e6368652d66756a692d31000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101985760003560e01c80636e861c0e116100e3578063b9bdccf31161008c578063d5b9221b11610066578063d5b9221b1461040c578063e93ce74f1461042f578063f2fde38b1461044257600080fd5b8063b9bdccf3146103d1578063bf8a793f146103e4578063cdc634f1146103f757600080fd5b80638da5cb5b116100bd5780638da5cb5b146103975780638dbe7b9d146103b5578063abb08b3f146103be57600080fd5b80636e861c0e14610369578063715018a61461037c57806388405e6c1461038457600080fd5b806333c0950a1161014557806346ce41751161011f57806346ce41751461033b578063603ea4981461034357806367561d931461035657600080fd5b806333c0950a146102a95780633f66286a146102cd57806345e1fa0d1461032857600080fd5b8063103aeda711610176578063103aeda71461020e57806324f74697146102575780632f73bab81461028857600080fd5b806309c1ba2e1461019d5780630ca76175146101cf5780630e599a73146101e4575b600080fd5b6005546101b19067ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b6101e26101dd366004612171565b610455565b005b600554610201906c01000000000000000000000000900460ff1681565b6040516101c6919061220d565b61024761021c36600461224e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526008602052604090205460ff1690565b60405190151581526020016101c6565b6005546102739068010000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016101c6565b61029b610296366004612284565b6104ff565b6040519081526020016101c6565b6102bc6102b7366004612284565b610597565b6040516101c695949392919061230b565b6103036102db366004612284565b60076020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c6565b6101e261033636600461238b565b6106b9565b60025461029b565b6101e26103513660046123cd565b6108c2565b6101e261036436600461224e565b610985565b6101e261037736600461224e565b610a16565b6101e2610aa1565b61024761039236600461238b565b610ab5565b60005473ffffffffffffffffffffffffffffffffffffffff16610303565b61029b60045481565b6101e26103cc366004612463565b610b1c565b61029b6103df3660046124af565b610bf5565b6101e26103f2366004612284565b610f45565b6103ff61102f565b6040516101c691906124fb565b61024761041a36600461224e565b60086020526000908152604090205460ff1681565b6101e261043d366004612284565b6110bd565b6101e261045036600461224e565b611161565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000f9b8fc078197181c841c296c876945aaa425b27816146104c4576040517fc6829f8300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104cf8383836111c2565b60405183907f85e1543bf2f84fe80c6badbce3648c8539ad1df4d2b3d822938ca0538be727e690600090a2505050565b6002546000908210610572576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f496e646578206f7574206f6620626f756e64730000000000000000000000000060448201526064015b60405180910390fd5b600282815481106105855761058561250e565b90600052602060002001549050919050565b60606000806000806000600160008881526020019081526020016000206040518060a00160405290816000820180546105cf9061253d565b80601f01602080910402602001604051908101604052809291908181526020018280546105fb9061253d565b80156106485780601f1061061d57610100808354040283529160200191610648565b820191906000526020600020905b81548152906001019060200180831161062b57829003601f168201915b505050505081526020016001820160009054906101000a900460ff161515151581526020016002820154815260200160038201548152602001600482015481525050905080600001518160200151826040015183606001518460800151955095509550955095505091939590929450565b6106c1611472565b600082826040516020016106d6929190612590565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600193849052919091209091015490915060ff161561078c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f50726f766964657220616c7265616479207265676973746572656400000000006044820152606401610569565b6040518060a0016040528084848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250938552505060016020808501829052426040808701829052606087019190915260809095018490528684525250208151819061080590826125ee565b506020820151600182810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001692151592909217909155604080840151600280850191909155606085015160038501556080909401516004909301929092558254908101835560009283527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018390555182917f32dfc590cafade73cbba6680180fc790a94eb0cfa92a3186559d6fb8864101dd91a2505050565b6108ca6114c5565b6108d2611472565b6005805463ffffffff861668010000000000000000027fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090911667ffffffffffffffff881617178082558491907fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff166c01000000000000000000000000836002811115610961576109616121de565b02179055506006610973828483612708565b5061097e6001600355565b5050505050565b61098d6114c5565b610995611472565b73ffffffffffffffffffffffffffffffffffffffff811660008181526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f8983a1f3c3cb45c24c8226b5b805e3b6eb49686530b808534b2a920129eff6519190a2610a136001600355565b50565b610a1e6114c5565b610a26611472565b73ffffffffffffffffffffffffffffffffffffffff811660008181526008602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f54142b7cb3ceaa9e564243ce4cc2303723c842a1144192de6b3c594f68b16a9a9190a2610a136001600355565b610aa9611472565b610ab36000611508565b565b6000808383604051602001610acb929190612590565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815260019283905220015460ff169150505b92915050565b610b24611472565b60008381526001602081905260409091200154839060ff16610ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f50726f7669646572206e6f7420726567697374657265640000000000000000006044820152606401610569565b600084815260016020526040902080610bbc848683612708565b5042600382015560405185907f04ed8331e86b605a92965a0cf623cd7bf9a5cd75ca23c4a139245bca110b59f390600090a25050505050565b6000610bff6114c5565b3360009081526008602052604090205460ff16610c4a576040517fe195aa13000000000000000000000000000000000000000000000000000000008152336004820152602401610569565b6000610c558361157d565b9050610c986040805160e0810190915280600081526020016000815260200160008152602001606081526020016060815260200160608152602001606081525090565b610ca5816000808561169a565b60055460208201906c01000000000000000000000000900460ff166002811115610cd157610cd16121de565b90816002811115610ce457610ce46121de565b90525060068054610cf49061253d565b80601f0160208091040260200160405190810160405280929190818152602001828054610d209061253d565b8015610d6d5780601f10610d4257610100808354040283529160200191610d6d565b820191906000526020600020905b815481529060010190602001808311610d5057829003601f168201915b50505050506080820152604080516001808252818301909252600091816020015b6060815260200190600190039081610d8e57905050905086868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250855186945090925015159050610def57610def61250e565b6020908102919091010152610e048282611731565b6000610e3c610e1284611774565b60055460045467ffffffffffffffff82169168010000000000000000900463ffffffff1690611af3565b6040517fe93ce74f00000000000000000000000000000000000000000000000000000000815260048101889052909150309063e93ce74f90602401600060405180830381600087803b158015610e9157600080fd5b505af1158015610ea5573d6000803e3d6000fd5b505050600082815260076020526040812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317905583517f7843201bc61dabd0c5d1ae50c3c5f42890f52e0e4499eb70174606c2b6686dab9250849190610f1257610f1261250e565b6020026020010151604051610f2791906124fb565b60405180910390a19350505050610f3e6001600355565b9392505050565b610f4d611472565b60008181526001602081905260409091200154819060ff16610fcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f50726f7669646572206e6f7420726567697374657265640000000000000000006044820152606401610569565b600082815260016020819052604080832090910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690555183917fd1983ea33649b47070f29135589ec31ac5dc7eab4e3882668d50929807b6f68691a25050565b6006805461103c9061253d565b80601f01602080910402602001604051908101604052809291908181526020018280546110689061253d565b80156110b55780601f1061108a576101008083540402835291602001916110b5565b820191906000526020600020905b81548152906001019060200180831161109857829003601f168201915b505050505081565b60008181526001602081905260409091200154819060ff1661113b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f50726f7669646572206e6f7420726567697374657265640000000000000000006044820152606401610569565b600082815260016020526040812060040180549161115883612851565b91905055505050565b611169611472565b73ffffffffffffffffffffffffffffffffffffffff81166111b9576040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260006004820152602401610569565b610a1381611508565b6111ca6114c5565b60008381526007602052604090205473ffffffffffffffffffffffffffffffffffffffff1680611256576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e76616c6964207265717565737420494400000000000000000000000000006044820152606401610569565b81511561129a57837f61982c98cbc49d11759a948f460b92bca26bdf12ceee12c310f117eb2ca9a9cb8360405161128d91906124fb565b60405180910390a26112d3565b837f1f4509cd59b6c74633bed4200a8e35803ebaa37d5d0e229640ed5fce1200b053846040516112ca91906124fb565b60405180910390a25b60008481526007602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555173ffffffffffffffffffffffffffffffffffffffff83169061133390879087908790602401612889565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fe3afe37200000000000000000000000000000000000000000000000000000000179052516113b491906128be565b6000604051808303816000865af19150503d80600081146113f1576040519150601f19603f3d011682016040523d82523d6000602084013e6113f6565b606091505b5050905080611461576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f43616c6c6261636b206661696c656400000000000000000000000000000000006044820152606401610569565b505061146d6001600355565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ab3576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610569565b600260035403611501576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002600355565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000818152600160208190526040909120015460609060ff166115fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f50726f7669646572206e6f7420726567697374657265640000000000000000006044820152606401610569565b600082815260016020526040902080546116159061253d565b80601f01602080910402602001604051908101604052809291908181526020018280546116419061253d565b801561168e5780601f106116635761010080835404028352916020019161168e565b820191906000526020600020905b81548152906001019060200180831161167157829003601f168201915b50505050509050919050565b80516000036116d5576040517f22ce3edd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b838360028111156116e8576116e86121de565b908160028111156116fb576116fb6121de565b90525060408401828015611711576117116121de565b90818015611721576117216121de565b9052506060909301929092525050565b805160000361176c576040517ffe936cb700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60a090910152565b60606000611783610100611bd2565b90506117cd6040518060400160405280600c81526020017f636f64654c6f636174696f6e000000000000000000000000000000000000000081525082611bf390919063ffffffff16565b82516117eb9060028111156117e4576117e46121de565b8290611c0c565b60408051808201909152600881527f6c616e6775616765000000000000000000000000000000000000000000000000602082015261182a908290611bf3565b60408301516118419080156117e4576117e46121de565b60408051808201909152600681527f736f7572636500000000000000000000000000000000000000000000000000006020820152611880908290611bf3565b6060830151611890908290611bf3565b60a0830151511561193d5760408051808201909152600481527f617267730000000000000000000000000000000000000000000000000000000060208201526118da908290611bf3565b6118e381611c49565b60005b8360a0015151811015611933576119238460a00151828151811061190c5761190c61250e565b602002602001015183611bf390919063ffffffff16565b61192c81612851565b90506118e6565b5061193d81611c6d565b60808301515115611a3e57600083602001516002811115611960576119606121de565b03611997576040517fa80d31f700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201909152600f81527f736563726574734c6f636174696f6e000000000000000000000000000000000060208201526119d6908290611bf3565b6119ef836020015160028111156117e4576117e46121de565b60408051808201909152600781527f73656372657473000000000000000000000000000000000000000000000000006020820152611a2e908290611bf3565b6080830151611a3e908290611c8b565b60c08301515115611aeb5760408051808201909152600981527f62797465734172677300000000000000000000000000000000000000000000006020820152611a88908290611bf3565b611a9181611c49565b60005b8360c0015151811015611ae157611ad18460c001518281518110611aba57611aba61250e565b602002602001015183611c8b90919063ffffffff16565b611ada81612851565b9050611a94565b50611aeb81611c6d565b515192915050565b6000807f000000000000000000000000f9b8fc078197181c841c296c876945aaa425b27873ffffffffffffffffffffffffffffffffffffffff1663461d27628688600188886040518663ffffffff1660e01b8152600401611b589594939291906128da565b6020604051808303816000875af1158015611b77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b9b9190612924565b60405190915081907f1131472297a800fee664d1d89cfa8f7676ff07189ecc53f80bbb5f4969099db890600090a295945050505050565b611bda612062565b8051611be69083611c98565b5060006020820152919050565b611c008260038351611d0f565b815161146d9082611e36565b8151611c199060c2611e57565b50611c458282604051602001611c3191815260200190565b604051602081830303815290604052611c8b565b5050565b611c54816004611ec0565b600181602001818151611c67919061293d565b90525050565b611c78816007611ec0565b600181602001818151611c679190612950565b611c008260028351611d0f565b604080518082019091526060815260006020820152611cb8602083612963565b15611ce057611cc8602083612963565b611cd3906020612950565b611cdd908361293d565b91505b602080840183905260405180855260008152908184010181811015611d0457600080fd5b604052509192915050565b60178167ffffffffffffffff1611611d3c578251611d369060e0600585901b168317611e57565b50505050565b60ff8167ffffffffffffffff1611611d7e578251611d65906018611fe0600586901b1617611e57565b508251611d369067ffffffffffffffff83166001611ed7565b61ffff8167ffffffffffffffff1611611dc1578251611da8906019611fe0600586901b1617611e57565b508251611d369067ffffffffffffffff83166002611ed7565b63ffffffff8167ffffffffffffffff1611611e06578251611ded90601a611fe0600586901b1617611e57565b508251611d369067ffffffffffffffff83166004611ed7565b8251611e1d90601b611fe0600586901b1617611e57565b508251611d369067ffffffffffffffff83166008611ed7565b604080518082019091526060815260006020820152610f3e83838451611f5c565b6040805180820190915260608152600060208201528251516000611e7c82600161293d565b905084602001518210611e9d57611e9d85611e9883600261299e565b61204b565b8451602083820101858153508051821115611eb6578181525b5093949350505050565b815161146d90601f611fe0600585901b1617611e57565b6040805180820190915260608152600060208201528351516000611efb828561293d565b90508560200151811115611f1857611f1886611e9883600261299e565b60006001611f2886610100612ad5565b611f329190612950565b90508651828101878319825116178152508051831115611f50578281525b50959695505050505050565b6040805180820190915260608152600060208201528251821115611f7f57600080fd5b8351516000611f8e848361293d565b90508560200151811115611fab57611fab86611e9883600261299e565b855180518382016020019160009180851115611fc5578482525b505050602086015b602086106120055780518252611fe460208361293d565b9150611ff160208261293d565b9050611ffe602087612950565b9550611fcd565b5181517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60208890036101000a0190811690199190911617905250849150509392505050565b81516120578383611c98565b50611d368382611e36565b604051806040016040528061208a604051806040016040528060608152602001600081525090565b8152602001600081525090565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126120d757600080fd5b813567ffffffffffffffff808211156120f2576120f2612097565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561213857612138612097565b8160405283815286602085880101111561215157600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561218657600080fd5b83359250602084013567ffffffffffffffff808211156121a557600080fd5b6121b1878388016120c6565b935060408601359150808211156121c757600080fd5b506121d4868287016120c6565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6020810160038310612248577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b91905290565b60006020828403121561226057600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610f3e57600080fd5b60006020828403121561229657600080fd5b5035919050565b60005b838110156122b85781810151838201526020016122a0565b50506000910152565b600081518084526122d981602086016020860161229d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60a08152600061231e60a08301886122c1565b95151560208301525060408101939093526060830191909152608090910152919050565b60008083601f84011261235457600080fd5b50813567ffffffffffffffff81111561236c57600080fd5b60208301915083602082850101111561238457600080fd5b9250929050565b6000806020838503121561239e57600080fd5b823567ffffffffffffffff8111156123b557600080fd5b6123c185828601612342565b90969095509350505050565b6000806000806000608086880312156123e557600080fd5b853567ffffffffffffffff80821682146123fe57600080fd5b90955060208701359063ffffffff8216821461241957600080fd5b9094506040870135906003821061242f57600080fd5b9093506060870135908082111561244557600080fd5b5061245288828901612342565b969995985093965092949392505050565b60008060006040848603121561247857600080fd5b83359250602084013567ffffffffffffffff81111561249657600080fd5b6124a286828701612342565b9497909650939450505050565b6000806000604084860312156124c457600080fd5b833567ffffffffffffffff8111156124db57600080fd5b6124e786828701612342565b909790965060209590950135949350505050565b602081526000610f3e60208301846122c1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c9082168061255157607f821691505b60208210810361258a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8183823760009101908152919050565b601f82111561146d57600081815260208120601f850160051c810160208610156125c75750805b601f850160051c820191505b818110156125e6578281556001016125d3565b505050505050565b815167ffffffffffffffff81111561260857612608612097565b61261c81612616845461253d565b846125a0565b602080601f83116001811461266f57600084156126395750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556125e6565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156126bc5788860151825594840194600190910190840161269d565b50858210156126f857878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff83111561272057612720612097565b6127348361272e835461253d565b836125a0565b6000601f84116001811461278657600085156127505750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b17835561097e565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156127d557868501358255602094850194600190920191016127b5565b5086821015612810577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361288257612882612822565b5060010190565b8381526060602082015260006128a260608301856122c1565b82810360408401526128b481856122c1565b9695505050505050565b600082516128d081846020870161229d565b9190910192915050565b67ffffffffffffffff8616815260a0602082015260006128fd60a08301876122c1565b61ffff9590951660408301525063ffffffff92909216606083015260809091015292915050565b60006020828403121561293657600080fd5b5051919050565b80820180821115610b1657610b16612822565b81810381811115610b1657610b16612822565b600082612999577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b8082028115828204841417610b1657610b16612822565b600181815b80851115612a0e57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156129f4576129f4612822565b80851615612a0157918102915b93841c93908002906129ba565b509250929050565b600082612a2557506001610b16565b81612a3257506000610b16565b8160018114612a485760028114612a5257612a6e565b6001915050610b16565b60ff841115612a6357612a63612822565b50506001821b610b16565b5060208310610133831016604e8410600b8410161715612a91575081810a610b16565b612a9b83836129b5565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115612acd57612acd612822565b029392505050565b6000610f3e8383612a1656fea2646970667358221220d8218751231908faa8e1bb856e6e1b36650ae0ebd312298aff50c3664356ec3664736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f9b8fc078197181c841c296c876945aaa425b27866756e2d6176616c616e6368652d66756a692d31000000000000000000000000
-----Decoded View---------------
Arg [0] : router (address): 0xf9B8fc078197181C841c296C876945aaa425B278
Arg [1] : _donId (bytes32): 0x66756e2d6176616c616e6368652d66756a692d31000000000000000000000000
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000f9b8fc078197181c841c296c876945aaa425b278
Arg [1] : 66756e2d6176616c616e6368652d66756a692d31000000000000000000000000
Loading...
Loading
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.