From 0f239478a0bef799ea81b7d1e2ac7666cd632b90 Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Fri, 4 Aug 2023 03:17:55 -0400 Subject: [PATCH] [Functions] (refactor): Various changes from review #3 (#10056) * Reapply: s_router is private * Create libraries folder, move Functions->FunctionsRequest & FunctionsResponse types in * Revert HasRouter back to Routable, add natspec * Separate Functions library Buffer import from CBOR * Functions library, using before all * (doc): Add more comments to Functions Request library * Document and clean up FunctionsClient * Geth wrappers * Add more ToS allowlist events * s_router -> i_router * RouterBase: timelock to uint64, remove doubled Paused getter, if statement revert style * Remove unused OCR hooks * make flags index var name more clear & add comment about internal function modifiers * Regenerate geth wrappers * Various size reducing measures * Save * Use ^v0.8.0 in openzeppelin-solidity/v4.8.0 * merge function base and router * Router config as typed struct * (test): Update tests * Use structs as getter return * Pull juelsPerGas into helper function * Add OracleWithdrawAll * Change multiline comments to single * Disable timelock propose and set in anticipation of MCM change * Regenerate geth wrappers * Add estimated cost to RequestStart * Fix foundry test * (test): Amend go integration test for Router constructor --------- Co-authored-by: Rens Rooimans --- .../functions/dev/1_0_0/FunctionsBilling.sol | 353 ++++++--------- .../dev/1_0_0/FunctionsCoordinator.sol | 59 ++- .../functions/dev/1_0_0/FunctionsRouter.sol | 344 ++++++++++++--- .../dev/1_0_0/FunctionsSubscriptions.sol | 324 ++++++-------- .../src/v0.8/functions/dev/1_0_0/Routable.sol | 34 +- .../v0.8/functions/dev/1_0_0/RouterBase.sol | 281 ------------ .../dev/1_0_0/interfaces/IConfigurable.sol | 10 +- .../1_0_0/interfaces/IFunctionsBilling.sol | 113 ++--- .../dev/1_0_0/interfaces/IFunctionsClient.sol | 16 +- .../interfaces/IFunctionsCoordinator.sol | 75 ++-- .../dev/1_0_0/interfaces/IFunctionsRouter.sol | 144 +++--- .../interfaces/IFunctionsSubscriptions.sol | 196 +++------ .../interfaces/IOwnableFunctionsRouter.sol | 4 +- .../dev/1_0_0/interfaces/IRouterBase.sol | 95 ---- .../dev/1_0_0/libraries/FunctionsRequest.sol | 70 ++- .../dev/1_0_0/libraries/FunctionsResponse.sol | 4 +- .../tests/1_0_0/FunctionsRouter.t.sol | 25 +- .../testhelpers/FunctionsClientTestHelper.sol | 2 - .../v4.8.0/contracts/interfaces/IERC5267.sol | 28 ++ .../contracts/interfaces/draft-IERC6093.sol | 160 +++++++ .../v4.8.0/contracts/token/ERC20/ERC20.sol | 370 ++++++++++++++++ .../v4.8.0/contracts/token/ERC20/IERC20.sol | 79 ++++ .../token/ERC20/extensions/ERC20Permit.sol | 84 ++++ .../token/ERC20/extensions/IERC20Metadata.sol | 26 ++ .../token/ERC20/extensions/IERC20Permit.sol | 60 +++ .../contracts/token/ERC20/utils/SafeERC20.sol | 140 ++++++ .../v4.8.0/contracts/utils/Nonces.sol | 46 ++ .../v4.8.0/contracts/utils/ShortStrings.sol | 122 ++++++ .../v4.8.0/contracts/utils/StorageSlot.sol | 135 ++++++ .../v4.8.0/contracts/utils/Strings.sol | 93 ++++ .../contracts/utils/cryptography/ECDSA.sol | 171 ++++++++ .../contracts/utils/cryptography/EIP712.sol | 160 +++++++ .../utils/cryptography/MessageHashUtils.sol | 87 ++++ .../v4.8.0/contracts/utils/math/Math.sol | 414 ++++++++++++++++++ .../contracts/utils/math/SignedMath.sol | 43 ++ .../v0.8/functions/v1/FunctionsRouter.test.ts | 10 +- .../test/v0.8/functions/v1/RouterBase.test.ts | 130 +++--- contracts/test/v0.8/functions/v1/utils.ts | 14 +- .../functions_coordinator.go | 138 +++--- .../functions_router/functions_router.go | 149 ++----- ...rapper-dependency-versions-do-not-edit.txt | 4 +- .../v1/internal/testutils.go | 14 +- 42 files changed, 3309 insertions(+), 1517 deletions(-) delete mode 100644 contracts/src/v0.8/functions/dev/1_0_0/RouterBase.sol delete mode 100644 contracts/src/v0.8/functions/dev/1_0_0/interfaces/IRouterBase.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC5267.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/draft-IERC6093.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/ERC20.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/ERC20Permit.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/IERC20Metadata.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/IERC20Permit.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Nonces.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/ShortStrings.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/StorageSlot.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Strings.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/ECDSA.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/EIP712.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/MessageHashUtils.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/Math.sol create mode 100644 contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SignedMath.sol diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol index 4d79a24e1bd..4a814d09e94 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsBilling.sol @@ -18,6 +18,8 @@ import {FunctionsResponse} from "./libraries/FunctionsResponse.sol"; abstract contract FunctionsBilling is Routable, IFunctionsBilling { using FunctionsResponse for FunctionsResponse.Commitment; using FunctionsResponse for FunctionsResponse.FulfillResult; + + uint32 private constant REASONABLE_GAS_PRICE_CEILING = 1_000_000; // ================================================================ // | Request Commitment state | // ================================================================ @@ -30,44 +32,8 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { // | Configuration state | // ================================================================ - struct Config { - // Maximum amount of gas that can be given to a request's client callback - uint32 maxCallbackGasLimit; - // feedStalenessSeconds is how long before we consider the feed price to be stale - // and fallback to fallbackNativePerUnitLink. - uint32 feedStalenessSeconds; - // Represents the average gas execution cost. Used in estimating cost beforehand. - uint32 gasOverheadBeforeCallback; - // Gas to cover transmitter oracle payment after we calculate the payment. - // We make it configurable in case those operations are repriced. - uint32 gasOverheadAfterCallback; - // how many seconds it takes before we consider a request to be timed out - uint32 requestTimeoutSeconds; - // additional flat fee (in Juels of LINK) that will be split between Node Operators - // Max value is 2^80 - 1 == 1.2m LINK. - uint80 donFee; - // The highest support request data version supported by the node - // All lower versions should also be supported - uint16 maxSupportedRequestDataVersion; - // Percentage of gas price overestimation to account for changes in gas price between request and response - // Held as basis points (one hundredth of 1 percentage point) - uint256 fulfillmentGasPriceOverEstimationBP; - // fallback NATIVE CURRENCY / LINK conversion rate if the data feed is stale - int256 fallbackNativePerUnitLink; - } - Config private s_config; - event ConfigChanged( - uint32 maxCallbackGasLimit, - uint32 feedStalenessSeconds, - uint32 gasOverheadBeforeCallback, - uint32 gasOverheadAfterCallback, - uint32 requestTimeoutSeconds, - uint80 donFee, - uint16 maxSupportedRequestDataVersion, - uint256 fulfillmentGasPriceOverEstimationBP, - int256 fallbackNativePerUnitLink - ); + event ConfigChanged(Config config); error UnsupportedRequestDataVersion(); error InsufficientBalance(); @@ -97,93 +63,31 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { } // ================================================================ - // | Configuration Methods | + // | Configuration | // ================================================================ - /** - * @notice Sets the configuration of the Chainlink Functions billing registry - * @param config bytes of abi.encoded config data to set the following: - * See the content of the Config struct above - */ + + // @notice Sets the configuration of the Chainlink Functions billing registry + // @param config bytes of abi.encoded config data to set the following: + // See the content of the Config struct above function _updateConfig(bytes memory config) internal override { - ( - uint32 maxCallbackGasLimit, - uint32 feedStalenessSeconds, - uint32 gasOverheadBeforeCallback, - uint32 gasOverheadAfterCallback, - uint32 requestTimeoutSeconds, - uint80 donFee, - uint16 maxSupportedRequestDataVersion, - uint256 fulfillmentGasPriceOverEstimationBP, - int256 fallbackNativePerUnitLink - ) = abi.decode(config, (uint32, uint32, uint32, uint32, uint32, uint80, uint16, uint256, int256)); - - if (fallbackNativePerUnitLink <= 0) { - revert InvalidLinkWeiPrice(fallbackNativePerUnitLink); + Config memory _config = abi.decode(config, (Config)); + if (_config.fallbackNativePerUnitLink <= 0) { + revert InvalidLinkWeiPrice(_config.fallbackNativePerUnitLink); } - s_config = Config({ - maxCallbackGasLimit: maxCallbackGasLimit, - feedStalenessSeconds: feedStalenessSeconds, - gasOverheadBeforeCallback: gasOverheadBeforeCallback, - gasOverheadAfterCallback: gasOverheadAfterCallback, - requestTimeoutSeconds: requestTimeoutSeconds, - donFee: donFee, - maxSupportedRequestDataVersion: maxSupportedRequestDataVersion, - fulfillmentGasPriceOverEstimationBP: fulfillmentGasPriceOverEstimationBP, - fallbackNativePerUnitLink: fallbackNativePerUnitLink - }); - emit ConfigChanged( - maxCallbackGasLimit, - feedStalenessSeconds, - gasOverheadBeforeCallback, - gasOverheadAfterCallback, - requestTimeoutSeconds, - donFee, - maxSupportedRequestDataVersion, - fulfillmentGasPriceOverEstimationBP, - fallbackNativePerUnitLink - ); + s_config = _config; + emit ConfigChanged(_config); } - /** - * @inheritdoc IFunctionsBilling - */ - function getConfig() - external - view - override - returns ( - uint32 maxCallbackGasLimit, - uint32 feedStalenessSeconds, - uint32 gasOverheadBeforeCallback, - uint32 gasOverheadAfterCallback, - uint32 requestTimeoutSeconds, - uint80 donFee, - uint16 maxSupportedRequestDataVersion, - uint256 fulfillmentGasPriceOverEstimationBP, - int256 fallbackNativePerUnitLink, - address linkPriceFeed - ) - { - return ( - s_config.maxCallbackGasLimit, - s_config.feedStalenessSeconds, - s_config.gasOverheadBeforeCallback, - s_config.gasOverheadAfterCallback, - s_config.requestTimeoutSeconds, - s_config.donFee, - s_config.maxSupportedRequestDataVersion, - s_config.fulfillmentGasPriceOverEstimationBP, - s_config.fallbackNativePerUnitLink, - address(s_linkToNativeFeed) - ); + // @inheritdoc IFunctionsBilling + function getConfig() external view override returns (Config memory) { + return s_config; } // ================================================================ - // | Cost Calculation Methods | + // | Fee Calculation | // ================================================================ - /** - * @inheritdoc IFunctionsBilling - */ + + // @inheritdoc IFunctionsBilling function getDONFee( bytes memory /* requestData */, RequestBilling memory /* billing */ @@ -192,92 +96,101 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { return s_config.donFee; } - /** - * @inheritdoc IFunctionsBilling - */ + // @inheritdoc IFunctionsBilling function getAdminFee() public view override returns (uint96) { - (, uint96 adminFee, , ) = _getRouter().getConfig(); - return adminFee; + return _getRouter().getConfig().adminFee; } - function getFeedData() public view returns (int256) { - uint32 feedStalenessSeconds = s_config.feedStalenessSeconds; - bool staleFallback = feedStalenessSeconds > 0; + // @inheritdoc IFunctionsBilling + function getWeiPerUnitLink() public view returns (uint256) { + Config memory config = s_config; (, int256 weiPerUnitLink, , uint256 timestamp, ) = s_linkToNativeFeed.latestRoundData(); // solhint-disable-next-line not-rely-on-time - if (staleFallback && feedStalenessSeconds < block.timestamp - timestamp) { - weiPerUnitLink = s_config.fallbackNativePerUnitLink; + if (config.feedStalenessSeconds < block.timestamp - timestamp && config.feedStalenessSeconds > 0) { + return uint256(config.fallbackNativePerUnitLink); } - return weiPerUnitLink; + if (weiPerUnitLink <= 0) { + revert InvalidLinkWeiPrice(weiPerUnitLink); + } + return uint256(weiPerUnitLink); + } + + function _getJuelsPerGas(uint256 gasPriceGwei) private view returns (uint256) { + // (1e18 juels/link) * (wei/gas) / (wei/link) = juels per gas + return (1e18 * gasPriceGwei) / getWeiPerUnitLink(); } // ================================================================ - // | Cost Estimation Methods | + // | Cost Estimation | // ================================================================ - /** - * @inheritdoc IFunctionsBilling - */ + + // @inheritdoc IFunctionsBilling function estimateCost( uint64 subscriptionId, bytes calldata data, uint32 callbackGasLimit, - uint256 gasPrice + uint256 gasPriceGwei ) external view override returns (uint96) { - // Reasonable ceilings to prevent integer overflows _getRouter().isValidCallbackGasLimit(subscriptionId, callbackGasLimit); - if (gasPrice > 1_000_000) { + // Reasonable ceilings to prevent integer overflows + if (gasPriceGwei > REASONABLE_GAS_PRICE_CEILING) { revert InvalidCalldata(); } uint96 adminFee = getAdminFee(); - RequestBilling memory billing = RequestBilling(subscriptionId, msg.sender, callbackGasLimit, gasPrice, adminFee); - uint96 donFee = getDONFee(data, billing); - return _calculateCostEstimate(callbackGasLimit, gasPrice, donFee, adminFee); + uint96 donFee = getDONFee( + data, + RequestBilling({ + subscriptionId: subscriptionId, + client: msg.sender, + callbackGasLimit: callbackGasLimit, + expectedGasPrice: gasPriceGwei, + adminFee: adminFee + }) + ); + return _calculateCostEstimate(callbackGasLimit, gasPriceGwei, donFee, adminFee); } - /** - * @notice Uses current price feed data to estimate a cost - */ + // @notice Estimate the cost in Juels of LINK + // that will be charged to a subscription to fulfill a Functions request + // Gas Price can be overestimated to account for flucuations between request and response time function _calculateCostEstimate( uint32 callbackGasLimit, - uint256 gasPrice, + uint256 gasPriceGwei, uint96 donFee, uint96 adminFee ) internal view returns (uint96) { - int256 weiPerUnitLink; - weiPerUnitLink = getFeedData(); - if (weiPerUnitLink <= 0) { - revert InvalidLinkWeiPrice(weiPerUnitLink); - } uint256 executionGas = s_config.gasOverheadBeforeCallback + s_config.gasOverheadAfterCallback + callbackGasLimit; - uint256 gasPriceWithOverestimation = gasPrice + - ((gasPrice * s_config.fulfillmentGasPriceOverEstimationBP) / 10_000); - // (1e18 juels/link) (wei/gas * gas) / (wei/link) = juels - uint256 paymentNoFee = (1e18 * gasPriceWithOverestimation * executionGas) / uint256(weiPerUnitLink); - uint256 fee = uint256(donFee) + uint256(adminFee); - if (paymentNoFee > (1e27 - fee)) { - revert PaymentTooLarge(); // Payment + fee cannot be more than all of the link in existence. - } - return uint96(paymentNoFee + fee); + + uint256 gasPriceWithOverestimation = gasPriceGwei + + ((gasPriceGwei * s_config.fulfillmentGasPriceOverEstimationBP) / 10_000); + // @NOTE: Basis Points are 1/100th of 1%, divide by 10_000 to bring back to original units + + uint256 juelsPerGas = _getJuelsPerGas(gasPriceWithOverestimation); + uint256 estimatedGasReimbursement = juelsPerGas * executionGas; + uint256 fees = uint256(donFee) + uint256(adminFee); + + return uint96(estimatedGasReimbursement + fees); } // ================================================================ - // | Billing Methods | + // | Billing | // ================================================================ - /** - * @notice Initiate the billing process for an Functions request - * @dev Only callable by the Functions Router - * @param data - Encoded Chainlink Functions request data, use FunctionsClient API to encode a request - * @param requestDataVersion - Version number of the structure of the request data - * @param billing - Billing configuration for the request - * @return commitment - The parameters of the request that must be held consistent at response time - */ + + // @notice Initiate the billing process for an Functions request + // @dev Only callable by the Functions Router + // @param data - Encoded Chainlink Functions request data, use FunctionsClient API to encode a request + // @param requestDataVersion - Version number of the structure of the request data + // @param billing - Billing configuration for the request + // @return commitment - The parameters of the request that must be held consistent at response time function _startBilling( bytes memory data, uint16 requestDataVersion, RequestBilling memory billing ) internal returns (FunctionsResponse.Commitment memory commitment) { + Config memory config = s_config; + // Nodes should support all past versions of the structure - if (requestDataVersion > s_config.maxSupportedRequestDataVersion) { + if (requestDataVersion > config.maxSupportedRequestDataVersion) { revert UnsupportedRequestDataVersion(); } @@ -289,15 +202,17 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { donFee, billing.adminFee ); - IFunctionsSubscriptions subscriptions = IFunctionsSubscriptions(address(_getRouter())); - (uint96 balance, , uint96 blockedBalance, , , ) = subscriptions.getSubscription(billing.subscriptionId); - (, uint64 initiatedRequests, ) = subscriptions.getConsumer(billing.client, billing.subscriptionId); - - if (balance - blockedBalance < estimatedCost) { + IFunctionsSubscriptions routerWithSubscriptions = IFunctionsSubscriptions(address(_getRouter())); + IFunctionsSubscriptions.Subscription memory subscription = routerWithSubscriptions.getSubscription( + billing.subscriptionId + ); + if ((subscription.balance - subscription.blockedBalance) < estimatedCost) { revert InsufficientBalance(); } - bytes32 requestId = computeRequestId(address(this), billing.client, billing.subscriptionId, initiatedRequests + 1); + (, uint64 initiatedRequests, ) = routerWithSubscriptions.getConsumer(billing.client, billing.subscriptionId); + + bytes32 requestId = _computeRequestId(address(this), billing.client, billing.subscriptionId, initiatedRequests + 1); commitment = FunctionsResponse.Commitment({ adminFee: billing.adminFee, @@ -306,20 +221,20 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { subscriptionId: billing.subscriptionId, callbackGasLimit: billing.callbackGasLimit, estimatedTotalCostJuels: estimatedCost, - timeoutTimestamp: uint40(block.timestamp + s_config.requestTimeoutSeconds), + timeoutTimestamp: uint40(block.timestamp + config.requestTimeoutSeconds), requestId: requestId, donFee: donFee, - gasOverheadBeforeCallback: s_config.gasOverheadBeforeCallback, - gasOverheadAfterCallback: s_config.gasOverheadAfterCallback + gasOverheadBeforeCallback: config.gasOverheadBeforeCallback, + gasOverheadAfterCallback: config.gasOverheadAfterCallback }); s_requestCommitments[requestId] = keccak256(abi.encode(commitment)); + + return commitment; } - /** - * @notice Generate a keccak hash request ID - */ - function computeRequestId( + // @notice Generate a keccak hash request ID + function _computeRequestId( address don, address client, uint64 subscriptionId, @@ -328,15 +243,13 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { return keccak256(abi.encode(don, client, subscriptionId, nonce)); } - /** - * @notice Finalize billing process for an Functions request by sending a callback to the Client contract and then charging the subscription - * @param requestId identifier for the request that was generated by the Registry in the beginBilling commitment - * @param response response data from DON consensus - * @param err error from DON consensus - * @return result fulfillment result - * @dev Only callable by a node that has been approved on the Coordinator - * @dev simulated offchain to determine if sufficient balance is present to fulfill the request - */ + // @notice Finalize billing process for an Functions request by sending a callback to the Client contract and then charging the subscription + // @param requestId identifier for the request that was generated by the Registry in the beginBilling commitment + // @param response response data from DON consensus + // @param err error from DON consensus + // @return result fulfillment result + // @dev Only callable by a node that has been approved on the Coordinator + // @dev simulated offchain to determine if sufficient balance is present to fulfill the request function _fulfillAndBill( bytes32 requestId, bytes memory response, @@ -345,21 +258,16 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { bytes memory /* offchainMetadata TODO: use in getDonFee() for dynamic billing */ ) internal returns (FunctionsResponse.FulfillResult) { FunctionsResponse.Commitment memory commitment = abi.decode(onchainMetadata, (FunctionsResponse.Commitment)); - if (s_requestCommitments[requestId] == bytes32(0)) { - return FunctionsResponse.FulfillResult.INVALID_REQUEST_ID; - } if (s_requestCommitments[requestId] != keccak256(abi.encode(commitment))) { return FunctionsResponse.FulfillResult.INVALID_COMMITMENT; } - int256 weiPerUnitLink; - weiPerUnitLink = getFeedData(); - if (weiPerUnitLink <= 0) { - revert InvalidLinkWeiPrice(weiPerUnitLink); + if (s_requestCommitments[requestId] == bytes32(0)) { + return FunctionsResponse.FulfillResult.INVALID_REQUEST_ID; } - // (1e18 juels/link) * (wei/gas) / (wei/link) = juels per gas - uint256 juelsPerGas = (1e18 * tx.gasprice) / uint256(weiPerUnitLink); + + uint256 juelsPerGas = _getJuelsPerGas(tx.gasprice); // Gas overhead without callback uint96 gasOverheadJuels = uint96( juelsPerGas * (commitment.gasOverheadBeforeCallback + commitment.gasOverheadAfterCallback) @@ -375,6 +283,9 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { commitment ); + // The router will only pay the DON on successfully processing the fulfillment + // In these two fulfillment results the user has been charged + // Otherwise, the Coordinator should hold on to the request commitment if ( resultCode == FunctionsResponse.FulfillResult.USER_SUCCESS || resultCode == FunctionsResponse.FulfillResult.USER_ERROR @@ -391,11 +302,11 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { } // ================================================================ - // | Request Timeout Methods | + // | Request Timeout | // ================================================================ - /** - * @inheritdoc IFunctionsBilling - */ + + // @inheritdoc IFunctionsBilling + // @dev used by FunctionsRouter.sol during timeout of a request function deleteCommitment(bytes32 requestId) external override onlyRouter returns (bool) { // Ensure that commitment exists if (s_requestCommitments[requestId] == bytes32(0)) { @@ -408,30 +319,47 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { } // ================================================================ - // | Node Operator methods | + // | Fund withdrawal | // ================================================================ - /* - * @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 - */ + + // @inheritdoc IFunctionsBilling function oracleWithdraw(address recipient, uint96 amount) external { _disperseFeePool(); if (amount == 0) { amount = s_withdrawableTokens[msg.sender]; - } - if (s_withdrawableTokens[msg.sender] < amount) { + } else if (s_withdrawableTokens[msg.sender] < amount) { revert InsufficientBalance(); } s_withdrawableTokens[msg.sender] -= amount; - IFunctionsSubscriptions router = IFunctionsSubscriptions(address(_getRouter())); - router.oracleWithdraw(recipient, amount); + IFunctionsSubscriptions(address(_getRouter())).oracleWithdraw(recipient, amount); + } + + // @inheritdoc IFunctionsBilling + // @dev Only callable by the Coordinator owner + function oracleWithdrawAll() external { + _onlyOwner(); + _disperseFeePool(); + + address[] memory transmitters = _getTransmitters(); + + // Bounded by "maxNumOracles" on OCR2Abstract.sol + for (uint256 i = 0; i < transmitters.length; ++i) { + uint96 balance = s_withdrawableTokens[msg.sender]; + s_withdrawableTokens[msg.sender] = 0; + IFunctionsSubscriptions(address(_getRouter())).oracleWithdraw(transmitters[i], balance); + } } + // Overriden in FunctionsCoordinator, which has visibility into transmitters + function _getTransmitters() internal view virtual returns (address[] memory); + + // DON fees are collected into a pool s_feePool + // When OCR configuration changes, or any oracle withdraws, this must be dispersed function _disperseFeePool() internal { + if (s_feePool == 0) { + return; + } // All transmitters are assumed to also be observers // Pay out the DON fee to all transmitters address[] memory transmitters = _getTransmitters(); @@ -446,5 +374,6 @@ abstract contract FunctionsBilling is Routable, IFunctionsBilling { s_feePool -= feePoolShare * uint96(transmitters.length); } - function _getTransmitters() internal view virtual returns (address[] memory); + // Overriden in FunctionsCoordinator.sol + function _onlyOwner() internal view virtual; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol index 179437ebb4d..34cd8d2aac2 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsCoordinator.sol @@ -9,11 +9,9 @@ import {FunctionsBilling} from "./FunctionsBilling.sol"; import {OCR2Base} from "./ocr/OCR2Base.sol"; import {FunctionsResponse} from "./libraries/FunctionsResponse.sol"; -/** - * @title Functions Coordinator contract - * @notice Contract that nodes of a Decentralized Oracle Network (DON) interact with - * @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. - */ +// @title Functions Coordinator contract +// @notice Contract that nodes of a Decentralized Oracle Network (DON) interact with +// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilling { using FunctionsResponse for FunctionsResponse.Commitment; using FunctionsResponse for FunctionsResponse.FulfillResult; @@ -50,9 +48,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli address linkToNativeFeed ) OCR2Base(true) FunctionsBilling(router, config, linkToNativeFeed) {} - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function getThresholdPublicKey() external view override returns (bytes memory) { if (s_thresholdPublicKey.length == 0) { revert EmptyPublicKey(); @@ -60,9 +56,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return s_thresholdPublicKey; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function setThresholdPublicKey(bytes calldata thresholdPublicKey) external override onlyOwner { if (thresholdPublicKey.length == 0) { revert EmptyPublicKey(); @@ -70,9 +64,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli s_thresholdPublicKey = thresholdPublicKey; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function getDONPublicKey() external view override returns (bytes memory) { if (s_donPublicKey.length == 0) { revert EmptyPublicKey(); @@ -80,9 +72,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return s_donPublicKey; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function setDONPublicKey(bytes calldata donPublicKey) external override onlyOwner { if (donPublicKey.length == 0) { revert EmptyPublicKey(); @@ -90,9 +80,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli s_donPublicKey = donPublicKey; } - /** - * @dev check if node is in current transmitter list - */ + // @dev check if node is in current transmitter list function _isTransmitter(address node) internal view returns (bool) { address[] memory nodes = s_transmitters; // Bounded by "maxNumOracles" on OCR2Abstract.sol @@ -104,9 +92,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return false; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function setNodePublicKey(address node, bytes calldata publicKey) external override { // Owner can set anything. Transmitters can set only their own key. if (!(msg.sender == owner() || (_isTransmitter(msg.sender) && msg.sender == node))) { @@ -115,9 +101,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli s_nodePublicKeys[node] = publicKey; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function deleteNodePublicKey(address node) external override { // Owner can delete anything. Others can delete only their own key. if (msg.sender != owner() && msg.sender != node) { @@ -126,25 +110,22 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli delete s_nodePublicKeys[node]; } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function getAllNodePublicKeys() external view override returns (address[] memory, bytes[] memory) { address[] memory nodes = s_transmitters; bytes[] memory keys = new bytes[](nodes.length); // Bounded by "maxNumOracles" on OCR2Abstract.sol for (uint256 i = 0; i < nodes.length; ++i) { - if (s_nodePublicKeys[nodes[i]].length == 0) { + bytes memory nodePublicKey = s_nodePublicKeys[nodes[i]]; + if (nodePublicKey.length == 0) { revert EmptyPublicKey(); } - keys[i] = s_nodePublicKeys[nodes[i]]; + keys[i] = nodePublicKey; } return (nodes, keys); } - /** - * @inheritdoc IFunctionsCoordinator - */ + // @inheritdoc IFunctionsCoordinator function sendRequest( Request calldata request ) external override onlyRouter returns (FunctionsResponse.Commitment memory commitment) { @@ -188,6 +169,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli return s_transmitters; } + // Report hook called within OCR2Base.sol function _report( uint256 /*initialGas*/, address /*transmitter*/, @@ -204,6 +186,7 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli report, (bytes32[], bytes[], bytes[], bytes[], bytes[]) ); + if ( requestIds.length == 0 || requestIds.length != results.length || @@ -220,6 +203,9 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli _fulfillAndBill(requestIds[i], results[i], errors[i], onchainMetadata[i], offchainMetadata[i]) ); + // Emit on successfully processing the fulfillment + // In these two fulfillment results the user has been charged + // Otherwise, the DON will re-try if ( result == FunctionsResponse.FulfillResult.USER_SUCCESS || result == FunctionsResponse.FulfillResult.USER_ERROR ) { @@ -227,4 +213,9 @@ contract FunctionsCoordinator is OCR2Base, IFunctionsCoordinator, FunctionsBilli } } } + + // Used in FunctionsBilling.sol + function _onlyOwner() internal view override { + _validateOwnership(); + } } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol index eb0dd1d84f9..be626f70b97 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsRouter.sol @@ -5,18 +5,19 @@ import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; import {IFunctionsRouter} from "./interfaces/IFunctionsRouter.sol"; import {IFunctionsCoordinator} from "./interfaces/IFunctionsCoordinator.sol"; import {IAccessController} from "../../../shared/interfaces/IAccessController.sol"; +import {IConfigurable} from "./interfaces/IConfigurable.sol"; -import {RouterBase} from "./RouterBase.sol"; import {FunctionsSubscriptions} from "./FunctionsSubscriptions.sol"; import {FunctionsResponse} from "./libraries/FunctionsResponse.sol"; +import {ConfirmedOwner} from "../../../ConfirmedOwner.sol"; import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/SafeCast.sol"; +import {Pausable} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/security/Pausable.sol"; -contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions { +contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, ITypeAndVersion, ConfirmedOwner { using FunctionsResponse for FunctionsResponse.Commitment; using FunctionsResponse for FunctionsResponse.FulfillResult; - // @inheritdoc ITypeAndVersion string public constant override typeAndVersion = "Functions Router v1.0.0"; // We limit return data to a selector plus 4 words. This is to avoid @@ -24,6 +25,13 @@ contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions // repeated out-of-gas scenarios. uint16 public constant MAX_CALLBACK_RETURN_BYTES = 4 + 4 * 32; + mapping(bytes32 id => address routableContract) private s_route; + + error RouteNotFound(bytes32 id); + + // Use empty bytes to self-identify, since it does not have an id + bytes32 private constant ROUTER_ID = bytes32(0); + event RequestStart( bytes32 indexed requestId, bytes32 indexed donId, @@ -33,7 +41,8 @@ contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions address requestInitiator, bytes data, uint16 dataVersion, - uint32 callbackGasLimit + uint32 callbackGasLimit, + uint96 estimatedTotalCostJuels ); event RequestProcessed( @@ -73,74 +82,155 @@ contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions // ================================================================ Config private s_config; - event ConfigChanged(uint96 adminFee, bytes4 handleOracleFulfillmentSelector, uint32[] maxCallbackGasLimits); + event ConfigChanged(Config); error OnlyCallableByRoute(); // ================================================================ - // | Initialization | + // | Timelock state | // ================================================================ + uint16 private immutable s_maximumTimelockBlocks; + uint16 private s_timelockBlocks; + + struct TimeLockProposal { + uint16 from; + uint16 to; + uint64 timelockEndBlock; + } + + TimeLockProposal private s_timelockProposal; + + event TimeLockProposed(uint16 from, uint16 to); + event TimeLockUpdated(uint16 from, uint16 to); + error ProposedTimelockAboveMaximum(); + error TimelockInEffect(); + + // ================================================================ + // | Proposal state | + // ================================================================ + + uint8 private constant MAX_PROPOSAL_SET_LENGTH = 8; + + struct ContractProposalSet { + bytes32[] ids; + address[] to; + uint64 timelockEndBlock; + } + ContractProposalSet private s_proposedContractSet; + + event ContractProposed( + bytes32 proposedContractSetId, + address proposedContractSetFromAddress, + address proposedContractSetToAddress, + uint64 timelockEndBlock + ); + + event ContractUpdated(bytes32 id, address from, address to); + + struct ConfigProposal { + bytes to; + uint64 timelockEndBlock; + } + mapping(bytes32 id => ConfigProposal) private s_proposedConfig; + event ConfigProposed(bytes32 id, bytes toBytes); + event ConfigUpdated(bytes32 id, bytes toBytes); + error InvalidProposal(); + error IdentifierIsReserved(bytes32 id); + constructor( uint16 timelockBlocks, uint16 maximumTimelockBlocks, address linkToken, - bytes memory config - ) RouterBase(msg.sender, timelockBlocks, maximumTimelockBlocks, config) FunctionsSubscriptions(linkToken) {} - - // ================================================================ - // | Getters | - // ================================================================ + Config memory config + ) FunctionsSubscriptions(linkToken) ConfirmedOwner(msg.sender) Pausable() { + // Set initial value for the number of blocks of the timelock + s_timelockBlocks = timelockBlocks; + // Set maximum number of blocks that the timelock can be + s_maximumTimelockBlocks = maximumTimelockBlocks; + // Set the initial configuration for the Router + s_route[ROUTER_ID] = address(this); + _updateConfig(config); + } // @inheritdoc IFunctionsRouter function getAllowListId() external pure override returns (bytes32) { return ALLOW_LIST_ID; } + // ================================================================ + // | Configuration | + // ================================================================ + // @inheritdoc IFunctionsRouter - function getConfig() - external - view - override - returns ( - uint16 maxConsumersPerSubscription, - uint96 adminFee, - bytes4 handleOracleFulfillmentSelector, - uint32[] memory maxCallbackGasLimits - ) - { - maxConsumersPerSubscription = s_config.maxConsumersPerSubscription; - adminFee = s_config.adminFee; - handleOracleFulfillmentSelector = s_config.handleOracleFulfillmentSelector; - maxCallbackGasLimits = s_config.maxCallbackGasLimits; + function getConfig() external view override returns (Config memory) { + return s_config; + } - return (maxConsumersPerSubscription, adminFee, handleOracleFulfillmentSelector, maxCallbackGasLimits); + // @inheritdoc IRouterBase + function proposeConfigUpdateSelf(bytes calldata config) external override onlyOwner { + s_proposedConfig[ROUTER_ID] = ConfigProposal({ + to: config, + timelockEndBlock: uint64(block.number + s_timelockBlocks) + }); + emit ConfigProposed({id: ROUTER_ID, toBytes: config}); } - // ================================================================ - // | Configuration methods | - // ================================================================ + // @inheritdoc IRouterBase + function updateConfigSelf() external override onlyOwner { + ConfigProposal memory proposal = s_proposedConfig[ROUTER_ID]; + if (block.number < proposal.timelockEndBlock) { + revert TimelockInEffect(); + } + _updateConfig(abi.decode(proposal.to, (Config))); + emit ConfigUpdated({id: ROUTER_ID, toBytes: proposal.to}); + } + + // @inheritdoc IRouterBase + function proposeConfigUpdate(bytes32 id, bytes calldata config) external override onlyOwner { + s_proposedConfig[id] = ConfigProposal({to: config, timelockEndBlock: uint64(block.number + s_timelockBlocks)}); + emit ConfigProposed({id: id, toBytes: config}); + } + + // @inheritdoc IRouterBase + function updateConfig(bytes32 id) external override onlyOwner { + ConfigProposal memory proposal = s_proposedConfig[id]; + + if (block.number < proposal.timelockEndBlock) { + revert TimelockInEffect(); + } + + IConfigurable(getContractById(id)).updateConfig(proposal.to); + + emit ConfigUpdated({id: id, toBytes: proposal.to}); + } // @notice Sets the configuration for FunctionsRouter specific state // @param config bytes of config data to set the following: // - adminFee: fee that will be paid to the Router owner for operating the network - function _updateConfig(bytes memory config) internal override { - ( - uint16 maxConsumersPerSubscription, - uint96 adminFee, - bytes4 handleOracleFulfillmentSelector, - uint32[] memory maxCallbackGasLimits - ) = abi.decode(config, (uint16, uint96, bytes4, uint32[])); - s_config = Config({ - maxConsumersPerSubscription: maxConsumersPerSubscription, - adminFee: adminFee, - handleOracleFulfillmentSelector: handleOracleFulfillmentSelector, - maxCallbackGasLimits: maxCallbackGasLimits - }); - emit ConfigChanged(adminFee, handleOracleFulfillmentSelector, maxCallbackGasLimits); + function _updateConfig(Config memory config) internal { + s_config = config; + emit ConfigChanged(config); + } + + // @inheritdoc IFunctionsRouter + function isValidCallbackGasLimit(uint64 subscriptionId, uint32 callbackGasLimit) public view { + uint8 callbackGasLimitsIndexSelector = uint8(getFlags(subscriptionId)[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]); + if (callbackGasLimitsIndexSelector >= s_config.maxCallbackGasLimits.length) { + revert InvalidGasFlagValue(callbackGasLimitsIndexSelector); + } + uint32 maxCallbackGasLimit = s_config.maxCallbackGasLimits[callbackGasLimitsIndexSelector]; + if (callbackGasLimit > maxCallbackGasLimit) { + revert GasLimitTooBig(maxCallbackGasLimit); + } + } + + // Used within FunctionsSubscriptions.sol + function _getMaxConsumers() internal view override returns (uint16) { + return s_config.maxConsumersPerSubscription; } // ================================================================ - // | Request methods | + // | Requests | // ================================================================ // @inheritdoc IFunctionsRouter @@ -224,12 +314,17 @@ contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions requestInitiator: tx.origin, data: data, dataVersion: dataVersion, - callbackGasLimit: callbackGasLimit + callbackGasLimit: callbackGasLimit, + estimatedTotalCostJuels: commitment.estimatedTotalCostJuels }); return commitment.requestId; } + // ================================================================ + // | Responses | + // ================================================================ + // @inheritdoc IFunctionsRouter function fulfill( bytes memory response, @@ -370,7 +465,7 @@ contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions if iszero(gt(sub(g, div(g, 64)), callbackGasLimit)) { revert(0, 0) } - // call and whether we succeeded + // call and report whether we succeeded // call(gas,addr,value,argsOffset,argsLength,retOffset,retLength) success := call(callbackGasLimit, client, 0, add(encodedCallback, 0x20), mload(encodedCallback), 0, 0) gasUsed := sub(g, gas()) @@ -389,20 +484,136 @@ contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions return CallbackResult({success: success, gasUsed: gasUsed, returnData: returnData}); } - // @inheritdoc IFunctionsRouter - function isValidCallbackGasLimit(uint64 subscriptionId, uint32 callbackGasLimit) public view { - uint8 callbackGasLimitsIndexSelector = uint8(getFlags(subscriptionId)[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]); - if (callbackGasLimitsIndexSelector >= s_config.maxCallbackGasLimits.length) { - revert InvalidGasFlagValue(callbackGasLimitsIndexSelector); + // ================================================================ + // | Route methods | + // ================================================================ + + // @inheritdoc IRouterBase + function getContractById(bytes32 id) public view override returns (address) { + address currentImplementation = s_route[id]; + if (currentImplementation == address(0)) { + revert RouteNotFound(id); } - uint32 maxCallbackGasLimit = s_config.maxCallbackGasLimits[callbackGasLimitsIndexSelector]; - if (callbackGasLimit > maxCallbackGasLimit) { - revert GasLimitTooBig(maxCallbackGasLimit); + return currentImplementation; + } + + // @inheritdoc IRouterBase + function getProposedContractById(bytes32 id) public view override returns (address) { + // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH + for (uint8 i = 0; i < s_proposedContractSet.ids.length; ++i) { + if (id == s_proposedContractSet.ids[i]) { + return s_proposedContractSet.to[i]; + } } + revert RouteNotFound(id); } - function _getMaxConsumers() internal view override returns (uint16) { - return s_config.maxConsumersPerSubscription; + // ================================================================ + // | Timelock | + // ================================================================ + + // removed in anticipation of using MCM + // TODO: fully remove + + // @inheritdoc IRouterBase + // function proposeTimelockBlocks(uint16 blocks) external override onlyOwner { + // if (s_timelockBlocks == blocks) { + // revert InvalidProposal(); + // } + // if (blocks > s_maximumTimelockBlocks) { + // revert ProposedTimelockAboveMaximum(); + // } + // s_timelockProposal = TimeLockProposal({ + // from: s_timelockBlocks, + // to: blocks, + // timelockEndBlock: uint64(block.number + s_timelockBlocks) + // }); + // } + + // @inheritdoc IRouterBase + // function updateTimelockBlocks() external override onlyOwner { + // if (block.number < s_timelockProposal.timelockEndBlock) { + // revert TimelockInEffect(); + // } + // s_timelockBlocks = s_timelockProposal.to; + // } + + // ================================================================ + // | Contract Proposal methods | + // ================================================================ + + // @inheritdoc IRouterBase + function getProposedContractSet() + external + view + override + returns (uint256 timelockEndBlock, bytes32[] memory ids, address[] memory to) + { + timelockEndBlock = s_proposedContractSet.timelockEndBlock; + ids = s_proposedContractSet.ids; + to = s_proposedContractSet.to; + return (timelockEndBlock, ids, to); + } + + // @inheritdoc IRouterBase + function proposeContractsUpdate( + bytes32[] memory proposedContractSetIds, + address[] memory proposedContractSetAddresses + ) external override onlyOwner { + // All arrays must be of equal length and not must not exceed the max length + uint256 idsArrayLength = proposedContractSetIds.length; + if (idsArrayLength != proposedContractSetAddresses.length || idsArrayLength > MAX_PROPOSAL_SET_LENGTH) { + revert InvalidProposal(); + } + // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH + for (uint256 i = 0; i < idsArrayLength; ++i) { + bytes32 id = proposedContractSetIds[i]; + address proposedContract = proposedContractSetAddresses[i]; + if ( + proposedContract == address(0) || // The Proposed address must be a valid address + s_route[id] == proposedContract // The Proposed address must point to a different address than what is currently set + ) { + revert InvalidProposal(); + } + // Reserved ids cannot be set + if (id == ROUTER_ID) { + revert IdentifierIsReserved(id); + } + } + + uint64 timelockEndBlock = uint64(block.number + s_timelockBlocks); + + s_proposedContractSet = ContractProposalSet({ + ids: proposedContractSetIds, + to: proposedContractSetAddresses, + timelockEndBlock: timelockEndBlock + }); + + // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH + for (uint256 i = 0; i < proposedContractSetIds.length; ++i) { + emit ContractProposed({ + proposedContractSetId: proposedContractSetIds[i], + proposedContractSetFromAddress: s_route[proposedContractSetIds[i]], + proposedContractSetToAddress: proposedContractSetAddresses[i], + timelockEndBlock: timelockEndBlock + }); + } + } + + // @inheritdoc IRouterBase + function updateContracts() external override onlyOwner { + if (block.number < s_proposedContractSet.timelockEndBlock) { + revert TimelockInEffect(); + } + // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH + for (uint256 i = 0; i < s_proposedContractSet.ids.length; ++i) { + bytes32 id = s_proposedContractSet.ids[i]; + address to = s_proposedContractSet.to[i]; + emit ContractUpdated({id: id, from: s_route[id], to: to}); + s_route[id] = to; + } + + delete s_proposedContractSet; } // ================================================================ @@ -422,8 +633,23 @@ contract FunctionsRouter is RouterBase, IFunctionsRouter, FunctionsSubscriptions // Used within FunctionsSubscriptions.sol function _onlySenderThatAcceptedToS() internal view override { - if (!IAccessController(getContractById(ALLOW_LIST_ID)).hasAccess(msg.sender, new bytes(0))) { + address currentImplementation = s_route[ALLOW_LIST_ID]; + if (currentImplementation == address(0)) { + // If not set, ignore this check + return; + } + if (!IAccessController(currentImplementation).hasAccess(msg.sender, new bytes(0))) { revert SenderMustAcceptTermsOfService(msg.sender); } } + + // @inheritdoc IRouterBase + function pause() external override onlyOwner { + _pause(); + } + + // @inheritdoc IRouterBase + function unpause() external override onlyOwner { + _unpause(); + } } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol index edfa91f2c36..2782dc7f99c 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/FunctionsSubscriptions.sol @@ -3,37 +3,43 @@ pragma solidity ^0.8.19; import {IFunctionsSubscriptions} from "./interfaces/IFunctionsSubscriptions.sol"; import {ERC677ReceiverInterface} from "../../../interfaces/ERC677ReceiverInterface.sol"; -import {LinkTokenInterface} from "../../../interfaces/LinkTokenInterface.sol"; import {IFunctionsBilling} from "./interfaces/IFunctionsBilling.sol"; import {IFunctionsRouter} from "./interfaces/IFunctionsRouter.sol"; import {FunctionsResponse} from "./libraries/FunctionsResponse.sol"; +import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol"; import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/utils/SafeCast.sol"; -/** - * @title Functions Subscriptions contract - * @notice Contract that coordinates payment from users to the nodes of the Decentralized Oracle Network (DON). - * @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. - */ +// @title Functions Subscriptions contract +// @notice Contract that coordinates payment from users to the nodes of the Decentralized Oracle Network (DON). +// @dev THIS CONTRACT HAS NOT GONE THROUGH ANY SECURITY REVIEW. DO NOT USE IN PROD. abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677ReceiverInterface { + using SafeERC20 for IERC20; using FunctionsResponse for FunctionsResponse.Commitment; + // ================================================================ - // | Subscription state | + // | Balance state | // ================================================================ + // link token address + address internal immutable i_linkToken; - // We make the sub count public so that its possible to - // get all the current subscriptions via getSubscription. - uint64 private s_currentSubscriptionId; - - // s_totalBalance tracks the total LINK sent to/from + // s_totalLinkBalance tracks the total LINK sent to/from // this contract through onTokenTransfer, cancelSubscription and oracleWithdraw. // A discrepancy with this contract's LINK balance indicates that someone // sent tokens using transfer and so we may need to use recoverFunds. - uint96 private s_totalBalance; + uint96 private s_totalLinkBalance; - // link token address - LinkTokenInterface private s_linkToken; + // @dev NOP balances are held as a single amount. The breakdown is held by the Coordinator. + mapping(address coordinator => uint96 balanceJuelsLink) private s_withdrawableTokens; + + // ================================================================ + // | Subscription state | + // ================================================================ + // Keep a count of the number of subscriptions so that its possible to + // loop through all the current subscriptions via .getSubscription(). + uint64 private s_currentSubscriptionId; mapping(uint64 subscriptionId => IFunctionsSubscriptions.Subscription) internal s_subscriptions; mapping(address consumer => mapping(uint64 subscriptionId => IFunctionsSubscriptions.Consumer)) internal s_consumers; @@ -55,13 +61,10 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei error InvalidCalldata(); error MustBeSubscriptionOwner(); error PendingRequestExists(); - error MustBeProposedOwner(); + error MustBeProposedOwner(address proposedOwner); error BalanceInvariantViolated(uint256 internalBalance, uint256 externalBalance); // Should never happen event FundsRecovered(address to, uint256 amount); - // @dev NOP balances are held as a single amount. The breakdown is held by the Coordinator. - mapping(address coordinator => uint96 balanceJuelsLink) private s_withdrawableTokens; - // ================================================================ // | Request state | // ================================================================ @@ -79,91 +82,15 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei // | Initialization | // ================================================================ constructor(address link) { - s_linkToken = LinkTokenInterface(link); + i_linkToken = link; } // ================================================================ - // | Getter methods | + // | Request/Response | // ================================================================ - /** - * @inheritdoc IFunctionsSubscriptions - */ - function getTotalBalance() external view override returns (uint96) { - return s_totalBalance; - } - - /** - * @inheritdoc IFunctionsSubscriptions - */ - function getSubscriptionCount() external view override returns (uint64) { - return s_currentSubscriptionId; - } - - /** - * @inheritdoc IFunctionsSubscriptions - */ - function getSubscription( - uint64 subscriptionId - ) - external - view - override - returns ( - uint96 balance, - address owner, - uint96 blockedBalance, - address requestedOwner, - address[] memory consumers, - bytes32 flags - ) - { - _isValidSubscription(subscriptionId); - - balance = s_subscriptions[subscriptionId].balance; - owner = s_subscriptions[subscriptionId].owner; - blockedBalance = s_subscriptions[subscriptionId].blockedBalance; - requestedOwner = s_subscriptions[subscriptionId].requestedOwner; - consumers = s_subscriptions[subscriptionId].consumers; - flags = s_subscriptions[subscriptionId].flags; - - return (balance, owner, blockedBalance, requestedOwner, consumers, flags); - } - /** - * @inheritdoc IFunctionsSubscriptions - */ - function getConsumer( - address client, - uint64 subscriptionId - ) external view override returns (bool allowed, uint64 initiatedRequests, uint64 completedRequests) { - allowed = s_consumers[client][subscriptionId].allowed; - initiatedRequests = s_consumers[client][subscriptionId].initiatedRequests; - completedRequests = s_consumers[client][subscriptionId].completedRequests; - } - - // ================================================================ - // | Internal validity checks | - // ================================================================ - - function _isValidSubscription(uint64 subscriptionId) internal view { - if (s_subscriptions[subscriptionId].owner == address(0)) { - revert InvalidSubscription(); - } - } - - function _isValidConsumer(address client, uint64 subscriptionId) internal view { - if (!s_consumers[client][subscriptionId].allowed) { - revert InvalidConsumer(); - } - } - - // ================================================================ - // | Internal Payment methods | - // ================================================================ - /** - * @notice Sets a request as in-flight - * @dev Only callable within the Router - */ + // @notice Sets a request as in-flight + // @dev Only callable within the Router function _markRequestInFlight(address client, uint64 subscriptionId, uint96 estimatedTotalCostJuels) internal { // Earmark subscription funds s_subscriptions[subscriptionId].blockedBalance += estimatedTotalCostJuels; @@ -172,10 +99,8 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei s_consumers[client][subscriptionId].initiatedRequests += 1; } - /** - * @notice Moves funds from one subscription account to another. - * @dev Only callable by the Coordinator contract that is saved in the request commitment - */ + // @notice Moves funds from one subscription account to another. + // @dev Only callable by the Coordinator contract that is saved in the request commitment function _pay( uint64 subscriptionId, uint96 estimatedTotalCostJuels, @@ -193,14 +118,15 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei // Charge the subscription s_subscriptions[subscriptionId].balance -= totalCostJuels; + // Unblock earmarked funds + s_subscriptions[subscriptionId].blockedBalance -= estimatedTotalCostJuels; + // Pay the DON's fees and gas reimbursement s_withdrawableTokens[msg.sender] += costWithoutCallbackJuels + callbackGasCostJuels; // Pay out the administration fee s_withdrawableTokens[address(this)] += adminFee; - // Unblock earmarked funds - s_subscriptions[subscriptionId].blockedBalance -= estimatedTotalCostJuels; // Increment finished requests s_consumers[client][subscriptionId].completedRequests += 1; @@ -210,62 +136,35 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei // ================================================================ // | Owner methods | // ================================================================ - /** - * @inheritdoc IFunctionsSubscriptions - */ + + // @inheritdoc IFunctionsSubscriptions function ownerCancelSubscription(uint64 subscriptionId) external override { _onlyRouterOwner(); _isValidSubscription(subscriptionId); _cancelSubscriptionHelper(subscriptionId, s_subscriptions[subscriptionId].owner); } - /** - * @inheritdoc IFunctionsSubscriptions - */ + // @inheritdoc IFunctionsSubscriptions function recoverFunds(address to) external override { _onlyRouterOwner(); - uint256 externalBalance = s_linkToken.balanceOf(address(this)); - uint256 internalBalance = uint256(s_totalBalance); + uint256 externalBalance = IERC20(i_linkToken).balanceOf(address(this)); + uint256 internalBalance = uint256(s_totalLinkBalance); if (internalBalance > externalBalance) { revert BalanceInvariantViolated(internalBalance, externalBalance); } if (internalBalance < externalBalance) { uint256 amount = externalBalance - internalBalance; - s_linkToken.transfer(to, amount); + IERC20(i_linkToken).safeTransfer(to, amount); emit FundsRecovered(to, amount); } // If the balances are equal, nothing to be done. } - /** - * @notice Owner withdraw LINK earned through admin fees - * @notice If amount is 0 the full balance will be withdrawn - * @param recipient where to send the funds - * @param amount amount to withdraw - */ - function ownerWithdraw(address recipient, uint96 amount) external { - _onlyRouterOwner(); - if (amount == 0) { - amount = s_withdrawableTokens[address(this)]; - } - if (s_withdrawableTokens[address(this)] < amount) { - revert InsufficientBalance(); - } - s_withdrawableTokens[address(this)] -= amount; - s_totalBalance -= amount; - if (!s_linkToken.transfer(recipient, amount)) { - uint256 externalBalance = s_linkToken.balanceOf(address(this)); - uint256 internalBalance = uint256(s_totalBalance); - revert BalanceInvariantViolated(internalBalance, externalBalance); - } - } - // ================================================================ - // | Coordinator methods | + // | Fund withdrawal | // ================================================================ - /** - * @inheritdoc IFunctionsSubscriptions - */ + + // @inheritdoc IFunctionsSubscriptions function oracleWithdraw(address recipient, uint96 amount) external override { _whenNotPaused(); @@ -276,18 +175,36 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei revert InsufficientBalance(); } s_withdrawableTokens[msg.sender] -= amount; - s_totalBalance -= amount; - if (!s_linkToken.transfer(recipient, amount)) { + s_totalLinkBalance -= amount; + IERC20(i_linkToken).safeTransfer(recipient, amount); + } + + // @notice Owner withdraw LINK earned through admin fees + // @notice If amount is 0 the full balance will be withdrawn + // @param recipient where to send the funds + // @param amount amount to withdraw + function ownerWithdraw(address recipient, uint96 amount) external { + _onlyRouterOwner(); + if (amount == 0) { + amount = s_withdrawableTokens[address(this)]; + } + if (s_withdrawableTokens[address(this)] < amount) { revert InsufficientBalance(); } + s_withdrawableTokens[address(this)] -= amount; + s_totalLinkBalance -= amount; + + IERC20(i_linkToken).safeTransfer(recipient, amount); } // ================================================================ - // | Deposit helper method | + // | TransferAndCall Deposit helper | // ================================================================ + + // This function is to be invoked when using LINK.transferAndCall function onTokenTransfer(address /* sender */, uint256 amount, bytes calldata data) external override { _whenNotPaused(); - if (msg.sender != address(s_linkToken)) { + if (msg.sender != address(i_linkToken)) { revert OnlyCallableFromLink(); } if (data.length != 32) { @@ -301,16 +218,55 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei // anyone can fund a subscription. uint256 oldBalance = s_subscriptions[subscriptionId].balance; s_subscriptions[subscriptionId].balance += uint96(amount); - s_totalBalance += uint96(amount); + s_totalLinkBalance += uint96(amount); emit SubscriptionFunded(subscriptionId, oldBalance, oldBalance + amount); } // ================================================================ - // | Subscription methods | + // | Subscriptions management | // ================================================================ - /** - * @inheritdoc IFunctionsSubscriptions - */ + + // @inheritdoc IFunctionsSubscriptions + function getTotalBalance() external view override returns (uint96) { + return s_totalLinkBalance; + } + + // @inheritdoc IFunctionsSubscriptions + function getSubscriptionCount() external view override returns (uint64) { + return s_currentSubscriptionId; + } + + // @inheritdoc IFunctionsSubscriptions + function getSubscription(uint64 subscriptionId) external view override returns (Subscription memory) { + _isValidSubscription(subscriptionId); + return s_subscriptions[subscriptionId]; + } + + // @inheritdoc IFunctionsSubscriptions + function getConsumer( + address client, + uint64 subscriptionId + ) external view override returns (bool allowed, uint64 initiatedRequests, uint64 completedRequests) { + allowed = s_consumers[client][subscriptionId].allowed; + initiatedRequests = s_consumers[client][subscriptionId].initiatedRequests; + completedRequests = s_consumers[client][subscriptionId].completedRequests; + } + + // Used within this file & FunctionsRouter.sol + function _isValidSubscription(uint64 subscriptionId) internal view { + if (s_subscriptions[subscriptionId].owner == address(0)) { + revert InvalidSubscription(); + } + } + + // Used within FunctionsRouter.sol + function _isValidConsumer(address client, uint64 subscriptionId) internal view { + if (!s_consumers[client][subscriptionId].allowed) { + revert InvalidConsumer(); + } + } + + // @inheritdoc IFunctionsSubscriptions function createSubscription() external override returns (uint64 subscriptionId) { _whenNotPaused(); _onlySenderThatAcceptedToS(); @@ -320,7 +276,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei balance: 0, blockedBalance: 0, owner: msg.sender, - requestedOwner: address(0), + proposedOwner: address(0), consumers: new address[](0), flags: bytes32(0) }); @@ -330,9 +286,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei return subscriptionId; } - /** - * @inheritdoc IFunctionsSubscriptions - */ + // @inheritdoc IFunctionsSubscriptions function proposeSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external override { _whenNotPaused(); _onlySubscriptionOwner(subscriptionId); @@ -340,31 +294,28 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei // Proposing to address(0) would never be claimable, so don't need to check. - if (s_subscriptions[subscriptionId].requestedOwner != newOwner) { - s_subscriptions[subscriptionId].requestedOwner = newOwner; + if (s_subscriptions[subscriptionId].proposedOwner != newOwner) { + s_subscriptions[subscriptionId].proposedOwner = newOwner; emit SubscriptionOwnerTransferRequested(subscriptionId, msg.sender, newOwner); } } - /** - * @inheritdoc IFunctionsSubscriptions - */ + // @inheritdoc IFunctionsSubscriptions function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external override { _whenNotPaused(); _onlySenderThatAcceptedToS(); address previousOwner = s_subscriptions[subscriptionId].owner; - if (s_subscriptions[subscriptionId].requestedOwner != msg.sender) { - revert MustBeProposedOwner(); + address proposedOwner = s_subscriptions[subscriptionId].proposedOwner; + if (proposedOwner != msg.sender) { + revert MustBeProposedOwner(proposedOwner); } s_subscriptions[subscriptionId].owner = msg.sender; - s_subscriptions[subscriptionId].requestedOwner = address(0); + s_subscriptions[subscriptionId].proposedOwner = address(0); emit SubscriptionOwnerTransferred(subscriptionId, previousOwner, msg.sender); } - /** - * @inheritdoc IFunctionsSubscriptions - */ + // @inheritdoc IFunctionsSubscriptions function removeConsumer(uint64 subscriptionId, address consumer) external override { _whenNotPaused(); _onlySubscriptionOwner(subscriptionId); @@ -392,9 +343,10 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei emit SubscriptionConsumerRemoved(subscriptionId, consumer); } - /** - * @inheritdoc IFunctionsSubscriptions - */ + // overriden in FunctionsRouter.sol + function _getMaxConsumers() internal view virtual returns (uint16); + + // @inheritdoc IFunctionsSubscriptions function addConsumer(uint64 subscriptionId, address consumer) external override { _whenNotPaused(); _onlySubscriptionOwner(subscriptionId); @@ -415,9 +367,7 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei emit SubscriptionConsumerAdded(subscriptionId, consumer); } - /** - * @inheritdoc IFunctionsSubscriptions - */ + // @inheritdoc IFunctionsSubscriptions function cancelSubscription(uint64 subscriptionId, address to) external override { _whenNotPaused(); _onlySubscriptionOwner(subscriptionId); @@ -439,16 +389,14 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei delete s_consumers[subscription.consumers[i]][subscriptionId]; } delete s_subscriptions[subscriptionId]; - s_totalBalance -= balance; - if (!s_linkToken.transfer(to, uint256(balance))) { - revert InsufficientBalance(); - } + s_totalLinkBalance -= balance; + + IERC20(i_linkToken).safeTransfer(to, uint256(balance)); + emit SubscriptionCanceled(subscriptionId, to, balance); } - /** - * @inheritdoc IFunctionsSubscriptions - */ + // @inheritdoc IFunctionsSubscriptions function pendingRequestExists(uint64 subscriptionId) public view override returns (bool) { address[] memory consumers = s_subscriptions[subscriptionId].consumers; // Iterations will not exceed config.maxConsumers @@ -461,30 +409,23 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei return false; } - /** - * @inheritdoc IFunctionsSubscriptions - */ + // @inheritdoc IFunctionsSubscriptions function setFlags(uint64 subscriptionId, bytes32 flags) external override { _onlyRouterOwner(); _isValidSubscription(subscriptionId); s_subscriptions[subscriptionId].flags = flags; } - /** - * @inheritdoc IFunctionsSubscriptions - */ + // @inheritdoc IFunctionsSubscriptions function getFlags(uint64 subscriptionId) public view returns (bytes32) { return s_subscriptions[subscriptionId].flags; } - function _getMaxConsumers() internal view virtual returns (uint16); - // ================================================================ - // | Request Timeout Methods | + // | Request Timeout | // ================================================================ - /** - * @inheritdoc IFunctionsSubscriptions - */ + + // @inheritdoc IFunctionsSubscriptions function timeoutRequests(FunctionsResponse.Commitment[] calldata requestsToTimeoutByCommitment) external override { _whenNotPaused(); @@ -528,9 +469,12 @@ abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, ERC677Recei } } + // Overriden in FunctionsRouter.sol function _onlySenderThatAcceptedToS() internal virtual; + // Overriden in FunctionsRouter.sol function _onlyRouterOwner() internal virtual; + // Overriden in FunctionsRouter.sol function _whenNotPaused() internal virtual; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol b/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol index cc057732b76..57b875bb52d 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/Routable.sol @@ -5,12 +5,10 @@ import {IConfigurable} from "./interfaces/IConfigurable.sol"; import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; import {IOwnableFunctionsRouter} from "./interfaces/IOwnableFunctionsRouter.sol"; -/** - * @title This abstract should be inherited by contracts that will be used - * as the destinations to a route (id=>contract) on the Router. - * It provides a Router getter and modifiers - * and enforces that the Router can update the configuration of this contract - */ +// @title This abstract should be inherited by contracts that will be used +// as the destinations to a route (id=>contract) on the Router. +// It provides a Router getter and modifiers +// and enforces that the Router can update the configuration of this contract abstract contract Routable is ITypeAndVersion, IConfigurable { IOwnableFunctionsRouter private immutable i_router; @@ -18,9 +16,7 @@ abstract contract Routable is ITypeAndVersion, IConfigurable { error OnlyCallableByRouter(); error OnlyCallableByRouterOwner(); - /** - * @dev Initializes the contract. - */ + // @dev Initializes the contract. constructor(address router, bytes memory config) { if (router == address(0)) { revert RouterMustBeSet(); @@ -33,23 +29,17 @@ abstract contract Routable is ITypeAndVersion, IConfigurable { return i_router; } - /** - * @dev Must be implemented by inheriting contract - * Use to set configuration state - */ + // @dev Must be implemented by inheriting contract + // Use to set configuration state function _updateConfig(bytes memory config) internal virtual; - /** - * @inheritdoc IConfigurable - * @dev Only callable by the Router - */ + // @inheritdoc IConfigurable + // @dev Only callable by the Router function updateConfig(bytes memory config) public override onlyRouter { _updateConfig(config); } - /** - * @notice Reverts if called by anyone other than the router. - */ + // @notice Reverts if called by anyone other than the router. modifier onlyRouter() { if (msg.sender != address(i_router)) { revert OnlyCallableByRouter(); @@ -57,9 +47,7 @@ abstract contract Routable is ITypeAndVersion, IConfigurable { _; } - /** - * @notice Reverts if called by anyone other than the router owner. - */ + // @notice Reverts if called by anyone other than the router owner. modifier onlyRouterOwner() { if (msg.sender != i_router.owner()) { revert OnlyCallableByRouterOwner(); diff --git a/contracts/src/v0.8/functions/dev/1_0_0/RouterBase.sol b/contracts/src/v0.8/functions/dev/1_0_0/RouterBase.sol deleted file mode 100644 index 2f665f14a90..00000000000 --- a/contracts/src/v0.8/functions/dev/1_0_0/RouterBase.sol +++ /dev/null @@ -1,281 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; -import {IRouterBase} from "./interfaces/IRouterBase.sol"; -import {IConfigurable} from "./interfaces/IConfigurable.sol"; - -import {ConfirmedOwner} from "../../../ConfirmedOwner.sol"; - -import {Pausable} from "../../../vendor/openzeppelin-solidity/v4.8.0/contracts/security/Pausable.sol"; - -abstract contract RouterBase is IRouterBase, Pausable, ITypeAndVersion, ConfirmedOwner { - // ================================================================ - // | Route state | - // ================================================================ - mapping(bytes32 id => address routableContract) private s_route; - - error RouteNotFound(bytes32 id); - - // Use empty bytes to self-identify, since it does not have an id - bytes32 private constant ROUTER_ID = bytes32(0); - - // ================================================================ - // | Proposal state | - // ================================================================ - - uint8 private constant MAX_PROPOSAL_SET_LENGTH = 8; - - struct ContractProposalSet { - bytes32[] ids; - address[] to; - uint64 timelockEndBlock; - } - ContractProposalSet private s_proposedContractSet; - - event ContractProposed( - bytes32 proposedContractSetId, - address proposedContractSetFromAddress, - address proposedContractSetToAddress, - uint64 timelockEndBlock - ); - - event ContractUpdated(bytes32 id, address from, address to); - - struct ConfigProposal { - bytes to; - uint64 timelockEndBlock; - } - mapping(bytes32 id => ConfigProposal) private s_proposedConfig; - event ConfigProposed(bytes32 id, bytes toBytes); - event ConfigUpdated(bytes32 id, bytes toBytes); - error InvalidProposal(); - error IdentifierIsReserved(bytes32 id); - - // ================================================================ - // | Timelock state | - // ================================================================ - uint16 private immutable s_maximumTimelockBlocks; - uint16 private s_timelockBlocks; - - struct TimeLockProposal { - uint16 from; - uint16 to; - uint64 timelockEndBlock; - } - - TimeLockProposal private s_timelockProposal; - - event TimeLockProposed(uint16 from, uint16 to); - event TimeLockUpdated(uint16 from, uint16 to); - error ProposedTimelockAboveMaximum(); - error TimelockInEffect(); - - // ================================================================ - // | Initialization | - // ================================================================ - - constructor( - address newOwner, - uint16 timelockBlocks, - uint16 maximumTimelockBlocks, - bytes memory selfConfig - ) ConfirmedOwner(newOwner) Pausable() { - // Set initial value for the number of blocks of the timelock - s_timelockBlocks = timelockBlocks; - // Set maximum number of blocks that the timelock can be - s_maximumTimelockBlocks = maximumTimelockBlocks; - // Set the initial configuration for the Router - s_route[ROUTER_ID] = address(this); - _updateConfig(selfConfig); - } - - // ================================================================ - // | Route methods | - // ================================================================ - - // @inheritdoc IRouterBase - function getContractById(bytes32 id) public view override returns (address) { - address currentImplementation = s_route[id]; - if (currentImplementation == address(0)) { - revert RouteNotFound(id); - } - return currentImplementation; - } - - // @inheritdoc IRouterBase - function getProposedContractById(bytes32 id) public view override returns (address) { - // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH - for (uint8 i = 0; i < s_proposedContractSet.ids.length; ++i) { - if (id == s_proposedContractSet.ids[i]) { - return s_proposedContractSet.to[i]; - } - } - revert RouteNotFound(id); - } - - // ================================================================ - // | Contract Proposal methods | - // ================================================================ - - // @inheritdoc IRouterBase - function getProposedContractSet() - external - view - override - returns (uint256 timelockEndBlock, bytes32[] memory ids, address[] memory to) - { - timelockEndBlock = s_proposedContractSet.timelockEndBlock; - ids = s_proposedContractSet.ids; - to = s_proposedContractSet.to; - return (timelockEndBlock, ids, to); - } - - // @inheritdoc IRouterBase - function proposeContractsUpdate( - bytes32[] memory proposedContractSetIds, - address[] memory proposedContractSetAddresses - ) external override onlyOwner { - // All arrays must be of equal length and not must not exceed the max length - uint256 idsArrayLength = proposedContractSetIds.length; - if (idsArrayLength != proposedContractSetAddresses.length || idsArrayLength > MAX_PROPOSAL_SET_LENGTH) { - revert InvalidProposal(); - } - // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH - for (uint256 i = 0; i < idsArrayLength; ++i) { - bytes32 id = proposedContractSetIds[i]; - address proposedContract = proposedContractSetAddresses[i]; - if ( - proposedContract == address(0) || // The Proposed address must be a valid address - s_route[id] == proposedContract // The Proposed address must point to a different address than what is currently set - ) { - revert InvalidProposal(); - } - // Reserved ids cannot be set - if (id == ROUTER_ID) { - revert IdentifierIsReserved(id); - } - } - - uint64 timelockEndBlock = uint64(block.number + s_timelockBlocks); - - s_proposedContractSet = ContractProposalSet({ - ids: proposedContractSetIds, - to: proposedContractSetAddresses, - timelockEndBlock: timelockEndBlock - }); - - // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH - for (uint256 i = 0; i < proposedContractSetIds.length; ++i) { - emit ContractProposed({ - proposedContractSetId: proposedContractSetIds[i], - proposedContractSetFromAddress: s_route[proposedContractSetIds[i]], - proposedContractSetToAddress: proposedContractSetAddresses[i], - timelockEndBlock: timelockEndBlock - }); - } - } - - // @inheritdoc IRouterBase - function updateContracts() external override onlyOwner { - if (block.number < s_proposedContractSet.timelockEndBlock) { - revert TimelockInEffect(); - } - // Iterations will not exceed MAX_PROPOSAL_SET_LENGTH - for (uint256 i = 0; i < s_proposedContractSet.ids.length; ++i) { - bytes32 id = s_proposedContractSet.ids[i]; - address to = s_proposedContractSet.to[i]; - emit ContractUpdated({id: id, from: s_route[id], to: to}); - s_route[id] = to; - } - - delete s_proposedContractSet; - } - - // ================================================================ - // | Config Proposal methods | - // ================================================================ - - // @dev Must be implemented by inheriting contract - // Use to set configuration state of the Router - function _updateConfig(bytes memory config) internal virtual; - - // @inheritdoc IRouterBase - function proposeConfigUpdateSelf(bytes calldata config) external override onlyOwner { - s_proposedConfig[ROUTER_ID] = ConfigProposal({ - to: config, - timelockEndBlock: uint64(block.number + s_timelockBlocks) - }); - emit ConfigProposed({id: ROUTER_ID, toBytes: config}); - } - - // @inheritdoc IRouterBase - function updateConfigSelf() external override onlyOwner { - ConfigProposal memory proposal = s_proposedConfig[ROUTER_ID]; - if (block.number < proposal.timelockEndBlock) { - revert TimelockInEffect(); - } - _updateConfig(proposal.to); - emit ConfigUpdated({id: ROUTER_ID, toBytes: proposal.to}); - } - - // @inheritdoc IRouterBase - function proposeConfigUpdate(bytes32 id, bytes calldata config) external override onlyOwner { - s_proposedConfig[id] = ConfigProposal({to: config, timelockEndBlock: uint64(block.number + s_timelockBlocks)}); - emit ConfigProposed({id: id, toBytes: config}); - } - - // @inheritdoc IRouterBase - function updateConfig(bytes32 id) external override onlyOwner { - ConfigProposal memory proposal = s_proposedConfig[id]; - - if (block.number < proposal.timelockEndBlock) { - revert TimelockInEffect(); - } - - IConfigurable(getContractById(id)).updateConfig(proposal.to); - - emit ConfigUpdated({id: id, toBytes: proposal.to}); - } - - // ================================================================ - // | Timelock methods | - // ================================================================ - - // @inheritdoc IRouterBase - function proposeTimelockBlocks(uint16 blocks) external override onlyOwner { - if (s_timelockBlocks == blocks) { - revert InvalidProposal(); - } - if (blocks > s_maximumTimelockBlocks) { - revert ProposedTimelockAboveMaximum(); - } - s_timelockProposal = TimeLockProposal({ - from: s_timelockBlocks, - to: blocks, - timelockEndBlock: uint64(block.number + s_timelockBlocks) - }); - } - - // @inheritdoc IRouterBase - function updateTimelockBlocks() external override onlyOwner { - if (block.number < s_timelockProposal.timelockEndBlock) { - revert TimelockInEffect(); - } - s_timelockBlocks = s_timelockProposal.to; - } - - // ================================================================ - // | Pausable methods | - // ================================================================ - - // @inheritdoc IRouterBase - function pause() external override onlyOwner { - _pause(); - } - - // @inheritdoc IRouterBase - function unpause() external override onlyOwner { - _unpause(); - } -} diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IConfigurable.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IConfigurable.sol index 6953bf37b09..4023aa282dd 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IConfigurable.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IConfigurable.sol @@ -1,13 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -/** - * @title Configurable contract interface. - */ +// @title Configurable contract interface. interface IConfigurable { - /** - * @notice Set the contract's configuration - * @param config bytes containing config data - */ + // @notice Set the contract's configuration + // @param config bytes containing config data function updateConfig(bytes calldata config) external; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol index f727bb192e1..3c401d0233e 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsBilling.sol @@ -1,9 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -/** - * @title Chainlink Functions billing subscription registry interface. - */ +// @title Chainlink Functions billing subscription registry interface. interface IFunctionsBilling { struct RequestBilling { // a unique subscription ID allocated by billing system, @@ -19,57 +17,56 @@ interface IFunctionsBilling { uint96 adminFee; } - /** - * @notice Gets the configuration of the Chainlink Functions billing registry - * @return maxCallbackGasLimit global max for request gas limit - * @return feedStalenessSeconds if the eth/link feed is more stale then this, use the fallback price - * @return gasOverheadBeforeCallback gas used in doing accounting before completing the gas measurement - * @return gasOverheadAfterCallback gas used in doing accounting after completing the gas measurement - * @return requestTimeoutSeconds e2e timeout for a request - * @return donFee extra fee added to every request - * @return maxSupportedRequestDataVersion The highest support request data version supported by the node - * @return fulfillmentGasPriceOverEstimationBP Percentage of gas price overestimation to account for changes in gas price between request and response. Held as basis points (one hundredth of 1 percentage point) - * @return fallbackNativePerUnitLink fallback native/link price in the case of a stale feed - * @return linkPriceFeed address of contract for a conversion price between LINK token and native token - */ - function getConfig() - external - view - returns ( - uint32 maxCallbackGasLimit, - uint32 feedStalenessSeconds, - uint32 gasOverheadBeforeCallback, - uint32 gasOverheadAfterCallback, - uint32 requestTimeoutSeconds, - uint80 donFee, - uint16 maxSupportedRequestDataVersion, - uint256 fulfillmentGasPriceOverEstimationBP, - int256 fallbackNativePerUnitLink, - address linkPriceFeed - ); + struct Config { + // Maximum amount of gas that can be given to a request's client callback + uint32 maxCallbackGasLimit; + // feedStalenessSeconds is how long before we consider the feed price to be stale + // and fallback to fallbackNativePerUnitLink. + uint32 feedStalenessSeconds; + // Represents the average gas execution cost. Used in estimating cost beforehand. + uint32 gasOverheadBeforeCallback; + // Gas to cover transmitter oracle payment after we calculate the payment. + // We make it configurable in case those operations are repriced. + uint32 gasOverheadAfterCallback; + // how many seconds it takes before we consider a request to be timed out + uint32 requestTimeoutSeconds; + // additional flat fee (in Juels of LINK) that will be split between Node Operators + // Max value is 2^80 - 1 == 1.2m LINK. + uint80 donFee; + // The highest support request data version supported by the node + // All lower versions should also be supported + uint16 maxSupportedRequestDataVersion; + // Percentage of gas price overestimation to account for changes in gas price between request and response + // Held as basis points (one hundredth of 1 percentage point) + uint256 fulfillmentGasPriceOverEstimationBP; + // fallback NATIVE CURRENCY / LINK conversion rate if the data feed is stale + int256 fallbackNativePerUnitLink; + } + + // @notice Gets the configuration of the Chainlink Functions billing registry + // @return config + function getConfig() external view returns (Config memory); + + // @notice Return the current conversion from WEI of ETH to LINK from the configured Chainlink data feed + // @return weiPerUnitLink - The amount of WEI in one LINK + function getWeiPerUnitLink() external view returns (uint256); - /** - * @notice Determine the fee that will be split between Node Operators for servicing a request - * @param requestData Encoded Chainlink Functions request data, use FunctionsClient API to encode a request - * @param billing The request's billing configuration - * @return fee Cost in Juels (1e18) of LINK - */ + // @notice Determine the fee that will be split between Node Operators for servicing a request + // @param requestData Encoded Chainlink Functions request data, use FunctionsClient API to encode a request + // @param billing The request's billing configuration + // @return fee Cost in Juels (1e18) of LINK function getDONFee(bytes memory requestData, RequestBilling memory billing) external view returns (uint80); - /** - * @notice Determine the fee that will be paid to the Router owner for operating the network - * @return fee Cost in Juels (1e18) of LINK - */ + // @notice Determine the fee that will be paid to the Router owner for operating the network + // @return fee Cost in Juels (1e18) of LINK function getAdminFee() external view returns (uint96); - /** - * @notice Estimate the total cost that will be charged to a subscription to make a request: gas re-reimbursement, plus DON fee, plus Registry fee - * @param subscriptionId An identifier of the billing account - * @param data Encoded Chainlink Functions request data, use FunctionsClient API to encode a request - * @param callbackGasLimit Gas limit for the fulfillment callback - * @param gasPrice The blockchain's gas price to estimate with - * @return billedCost Cost in Juels (1e18) of LINK - */ + // @notice Estimate the total cost that will be charged to a subscription to make a request: gas re-reimbursement, plus DON fee, plus Registry fee + // @param subscriptionId An identifier of the billing account + // @param data Encoded Chainlink Functions request data, use FunctionsClient API to encode a request + // @param callbackGasLimit Gas limit for the fulfillment callback + // @param gasPrice The blockchain's gas price to estimate with + // @return billedCost Cost in Juels (1e18) of LINK function estimateCost( uint64 subscriptionId, bytes calldata data, @@ -77,10 +74,18 @@ interface IFunctionsBilling { uint256 gasPrice ) external view returns (uint96); - /** - * @notice Remove a request commitment that the Router has determined to be stale - * @dev Only callable by the Router - * @param requestId - The request ID to remove - */ + // @notice Remove a request commitment that the Router has determined to be stale + // @dev Only callable by the Router + // @param requestId - The request ID to remove function deleteCommitment(bytes32 requestId) external returns (bool); + + // @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 Oracle withdraw all LINK earned through fulfilling requests to all Node Operators + function oracleWithdrawAll() external; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol index 4423ec6dcca..0a66c259cab 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsClient.sol @@ -1,16 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -/** - * @title Chainlink Functions client interface. - */ +// @title Chainlink Functions client interface. interface IFunctionsClient { - /** - * @notice Chainlink Functions response handler called by the designated transmitter node in an OCR round. - * @param requestId The requestId returned by FunctionsClient.sendRequest(). - * @param response Aggregated response from the user code. - * @param err Aggregated error either from the user code or from the execution pipeline. - * Either response or error parameter will be set, but never both. - */ + // @notice Chainlink Functions response handler called by the designated transmitter node in an OCR round. + // @param requestId The requestId returned by FunctionsClient.sendRequest(). + // @param response Aggregated response from the user code. + // @param err Aggregated error either from the user code or from the execution pipeline. + // Either response or error parameter will be set, but never both. function handleOracleFulfillment(bytes32 requestId, bytes memory response, bytes memory err) external; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol index 22fc505a8e7..5bd915b9ef0 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsCoordinator.sol @@ -3,9 +3,8 @@ pragma solidity ^0.8.19; import {FunctionsResponse} from "../libraries/FunctionsResponse.sol"; -/** - * @title Chainlink Functions oracle interface. - */ +// @title Chainlink Functions oracle interface. + interface IFunctionsCoordinator { struct Request { address requestingContract; // The client contract that is sending the request @@ -18,62 +17,46 @@ interface IFunctionsCoordinator { uint96 adminFee; // Flat fee (in Juels of LINK) that will be paid to the Router owner for operation of the network } - /** - * @notice Returns the DON's threshold encryption public key used to encrypt secrets - * @dev All nodes on the DON have separate key shares of the threshold decryption key - * and nodes must participate in a threshold decryption OCR round to decrypt secrets - * @return thresholdPublicKey the DON's threshold encryption public key - */ + // @notice Returns the DON's threshold encryption public key used to encrypt secrets + // @dev All nodes on the DON have separate key shares of the threshold decryption key + // and nodes must participate in a threshold decryption OCR round to decrypt secrets + // @return thresholdPublicKey the DON's threshold encryption public key function getThresholdPublicKey() external view returns (bytes memory); - /** - * @notice Sets the DON's threshold encryption public key used to encrypt secrets - * @dev Used to rotate the key - * @param thresholdPublicKey The new public key - */ + // @notice Sets the DON's threshold encryption public key used to encrypt secrets + // @dev Used to rotate the key + // @param thresholdPublicKey The new public key function setThresholdPublicKey(bytes calldata thresholdPublicKey) external; - /** - * @notice Returns the DON's secp256k1 public key that is used to encrypt secrets - * @dev All nodes on the DON have the corresponding private key - * needed to decrypt the secrets encrypted with the public key - * @return publicKey the DON's public key - */ + // @notice Returns the DON's secp256k1 public key that is used to encrypt secrets + // @dev All nodes on the DON have the corresponding private key + // needed to decrypt the secrets encrypted with the public key + // @return publicKey the DON's public key function getDONPublicKey() external view returns (bytes memory); - /** - * @notice Sets DON's secp256k1 public key used to encrypt secrets - * @dev Used to rotate the key - * @param donPublicKey The new public key - */ + // @notice Sets DON's secp256k1 public key used to encrypt secrets + // @dev Used to rotate the key + // @param donPublicKey The new public key function setDONPublicKey(bytes calldata donPublicKey) external; - /** - * @notice Sets a per-node secp256k1 public key used to encrypt secrets for that node - * @dev Callable only by contract owner and DON members - * @param node node's address - * @param publicKey node's public key - */ + // @notice Sets a per-node secp256k1 public key used to encrypt secrets for that node + // @dev Callable only by contract owner and DON members + // @param node node's address + // @param publicKey node's public key function setNodePublicKey(address node, bytes calldata publicKey) external; - /** - * @notice Deletes node's public key - * @dev Callable only by contract owner or the node itself - * @param node node's address - */ + // @notice Deletes node's public key + // @dev Callable only by contract owner or the node itself + // @param node node's address function deleteNodePublicKey(address node) external; - /** - * @notice Return two arrays of equal size containing DON members' addresses and their corresponding - * public keys (or empty byte arrays if per-node key is not defined) - */ + // @notice Return two arrays of equal size containing DON members' addresses and their corresponding + // public keys (or empty byte arrays if per-node key is not defined) function getAllNodePublicKeys() external view returns (address[] memory, bytes[] memory); - /** - * @notice Sends a request (encoded as data) using the provided subscriptionId - * @dev Callable only by the Router - * @param request The request information, @dev see the struct for field descriptions - * @return commitment - The parameters of the request that must be held consistent at response time - */ + // @notice Sends a request (encoded as data) using the provided subscriptionId + // @dev Callable only by the Router + // @param request The request information, @dev see the struct for field descriptions + // @return commitment - The parameters of the request that must be held consistent at response time function sendRequest(Request calldata request) external returns (FunctionsResponse.Commitment memory commitment); } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol index 6a0e50452df..c88dcd7e079 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsRouter.sol @@ -1,13 +1,10 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {IRouterBase} from "./IRouterBase.sol"; import {FunctionsResponse} from "../libraries/FunctionsResponse.sol"; -/** - * @title Chainlink Functions Router interface. - */ -interface IFunctionsRouter is IRouterBase { +// @title Chainlink Functions Router interface. +interface IFunctionsRouter { struct Config { // Maximum number of consumers which can be added to a single subscription // This bound ensures we are able to loop over all subscription consumers as needed, @@ -22,28 +19,22 @@ interface IFunctionsRouter is IRouterBase { uint32[] maxCallbackGasLimits; } - /** - * @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 - */ + // @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 pure returns (bytes32); - /** - * @notice The router configuration - */ - function getConfig() external view returns (uint16, uint96, bytes4, uint32[] memory); - - /** - * @notice Sends a request (encoded as data) 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 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 - */ + // @notice The router configuration + function getConfig() external view returns (Config memory); + + // @notice Sends a request (encoded as data) 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 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, @@ -52,16 +43,14 @@ interface IFunctionsRouter is IRouterBase { bytes32 donId ) external returns (bytes32); - /** - * @notice Sends a request (encoded as data) 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 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 - */ + // @notice Sends a request (encoded as data) 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 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, @@ -70,20 +59,18 @@ interface IFunctionsRouter is IRouterBase { 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 - - */ + // @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, @@ -93,10 +80,59 @@ interface IFunctionsRouter is IRouterBase { 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 - */ + // @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 timelockEndBlock The block number that the proposal is able to be merged at + // @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 (uint, 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 once timelock has passed + // @dev Only callable by owner + function updateContracts() external; + + // @notice Proposes new configuration data for the Router contract itself + // @dev Only callable by owner + function proposeConfigUpdateSelf(bytes calldata config) external; + + // @notice Updates configuration data for the Router contract itself + // @dev Only callable once timelock has passed + // @dev Only callable by owner + function updateConfigSelf() external; + + // @notice Proposes new configuration data for the current (not proposed) contract + // @dev Only callable by owner + function proposeConfigUpdate(bytes32 id, bytes calldata config) external; + + // @notice Sends new configuration data to the contract along a route route + // @dev Only callable once timelock has passed + // @dev Only callable by owner + function updateConfig(bytes32 id) 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; } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol index 7ee877eaa46..698930a6e2a 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IFunctionsSubscriptions.sol @@ -12,7 +12,7 @@ interface IFunctionsSubscriptions { uint96 balance; // Common LINK balance that is controlled by the Registry to be used for all consumer requests. address owner; // Owner can fund/withdraw/cancel the sub. uint96 blockedBalance; // LINK balance that is reserved to pay for pending consumer requests. - address requestedOwner; // For safely transferring sub ownership. + address proposedOwner; // For safely transferring sub ownership. // Maintains the list of keys in s_consumers. // We do this for 2 reasons: // 1. To be able to clean up all keys from s_consumers when canceling a subscription. @@ -29,161 +29,109 @@ interface IFunctionsSubscriptions { uint64 completedRequests; // The number of requests that have successfully completed or timed out } - /** - * @notice Get details about a subscription. - * @param subscriptionId - ID of the subscription - * @return balance - Common LINK balance that is controlled by the Registry to be used for all consumer requests. - * @return owner - Owner can fund/withdraw/cancel the sub. - * @return blockedBalance - LINK balance that is reserved to pay for pending consumer requests. - * @return requestedOwner - For safely transferring sub ownership. - * @return consumers - Client contracts that can use the subscription - * @return flags - Per-subscription flags. - */ - function getSubscription( - uint64 subscriptionId - ) - external - view - returns ( - uint96 balance, - address owner, - uint96 blockedBalance, - address requestedOwner, - address[] memory consumers, - bytes32 flags - ); - - /** - * @notice Get details about a consumer of a subscription. - * @dev Only callable by a route - * @param client - the consumer contract that initiated the request - * @param subscriptionId - ID of the subscription - * @return allowed - amount of LINK balance of the subscription in juels that is blocked for an in flight request. - * @return initiatedRequests - owner of the subscription. - * @return completedRequests - list of consumer address which are able to use this subscription. - */ + // @notice Get details about a subscription. + // @param subscriptionId - ID of the subscription + function getSubscription(uint64 subscriptionId) external view returns (Subscription memory); + + // @notice Get details about a consumer of a subscription. + // @dev Only callable by a route + // @param client - the consumer contract that initiated the request + // @param subscriptionId - ID of the subscription + // @return allowed - amount of LINK balance of the subscription in juels that is blocked for an in flight request. + // @return initiatedRequests - owner of the subscription. + // @return completedRequests - list of consumer address which are able to use this subscription. function getConsumer( address client, uint64 subscriptionId ) external view returns (bool allowed, uint64 initiatedRequests, uint64 completedRequests); - /** - * @notice Get details about the total amount of LINK within the system - * @return totalBalance - total Juels of LINK held by the contract - */ + // @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 - */ + // @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. - */ + // @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 - * @dev Must be called by the Coordinator contract - * @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 - */ + // @notice Oracle withdraw LINK earned through fulfilling requests + // @dev Must be called by the Coordinator contract + // @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 - */ + // @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 - */ + // @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(REGISTRY), - * @dev amount, - * @dev abi.encode(subscriptionId)); - */ + // @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(REGISTRY), + // @dev amount, + // @dev abi.encode(subscriptionId)); function createSubscription() external returns (uint64); - /** - * @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 - */ + // @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. - */ + // @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 - */ + // @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 - */ + // @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 - */ + // @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. - */ + // @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 flags for a given subscription. - * @param subscriptionId - ID of the subscription - * @param flags - desired flag values - */ + // @notice Set flags for a given subscription. + // @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 - */ + // @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); } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol index e0c6be5aa9b..8fdd5fb68c2 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IOwnableFunctionsRouter.sol @@ -4,9 +4,7 @@ pragma solidity ^0.8.19; import {IFunctionsRouter} from "./IFunctionsRouter.sol"; import {IOwnable} from "../../../../shared/interfaces/IOwnable.sol"; -/** - * @title Chainlink Functions Router interface with Ownable. - */ +// @title Chainlink Functions Router interface with Ownable. interface IOwnableFunctionsRouter is IOwnable, IFunctionsRouter { } diff --git a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IRouterBase.sol b/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IRouterBase.sol deleted file mode 100644 index 48167e2b1c0..00000000000 --- a/contracts/src/v0.8/functions/dev/1_0_0/interfaces/IRouterBase.sol +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -/** - * @title Chainlink base Router interface. - */ -interface IRouterBase { - /** - * @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 timelockEndBlock The block number that the proposal is able to be merged at - * @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 (uint, 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 once timelock has passed - * @dev Only callable by owner - */ - function updateContracts() external; - - /** - * @notice Proposes new configuration data for the Router contract itself - * @dev Only callable by owner - */ - function proposeConfigUpdateSelf(bytes calldata config) external; - - /** - * @notice Updates configuration data for the Router contract itself - * @dev Only callable once timelock has passed - * @dev Only callable by owner - */ - function updateConfigSelf() external; - - /** - * @notice Proposes new configuration data for the current (not proposed) contract - * @dev Only callable by owner - */ - function proposeConfigUpdate(bytes32 id, bytes calldata config) external; - - /** - * @notice Sends new configuration data to the contract along a route route - * @dev Only callable once timelock has passed - * @dev Only callable by owner - */ - function updateConfig(bytes32 id) external; - - /** - * @notice Propose a change to the amount of blocks of the timelock - * (the amount of blocks that are required to pass before a change can be applied) - * @dev Only callable by owner - */ - function proposeTimelockBlocks(uint16 blocks) external; - - /** - * @notice Apply a proposed change to the amount of blocks required for the timelock - * (the amount of blocks that are required to pass before a change can be applied) - * @dev Only callable after the timelock blocks proposal has gone through the timelock itself - * @dev Only callable by owner - */ - function updateTimelockBlocks() 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; -} diff --git a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol index 7cb330a3606..59e9fe9ba59 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsRequest.sol @@ -3,9 +3,7 @@ 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 - */ +// @title Library for encoding the input data of a Functions request into CBOR library FunctionsRequest { using CBOR for CBOR.CBORBuffer; @@ -38,11 +36,9 @@ library FunctionsRequest { error EmptyArgs(); error NoInlineSecrets(); - /** - * @notice Encodes a Request to CBOR encoded bytes - * @param self The request to encode - * @return CBOR encoded bytes - */ + // @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); @@ -86,14 +82,12 @@ library FunctionsRequest { 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 - */ + // @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, @@ -107,21 +101,17 @@ library FunctionsRequest { 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) - */ + // @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 - */ + // @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(); @@ -129,12 +119,10 @@ library FunctionsRequest { 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) - */ + // @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); @@ -147,22 +135,18 @@ library FunctionsRequest { 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) - */ + // @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) - */ + // @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(); diff --git a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol index 6421ee6b44b..d0d8512af17 100644 --- a/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol +++ b/contracts/src/v0.8/functions/dev/1_0_0/libraries/FunctionsResponse.sol @@ -1,9 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -/** - * @title Library of types that are used during fulfillment of a Functions request - */ +// @title Library of types that are used during fulfillment of a Functions request library FunctionsResponse { enum FulfillResult { USER_SUCCESS, // 0 diff --git a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol index 10a27ae78ba..edc29477caa 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/FunctionsRouter.t.sol @@ -2,6 +2,7 @@ pragma solidity ^0.8.0; import {IFunctionsRouter} from "../../dev/1_0_0/interfaces/IFunctionsRouter.sol"; +import {IFunctionsBilling} from "../../dev/1_0_0/interfaces/IFunctionsBilling.sol"; import {BaseTest} from "./BaseTest.t.sol"; import {FunctionsRouter} from "../../dev/1_0_0/FunctionsRouter.sol"; @@ -34,29 +35,21 @@ contract FunctionsRouterSetup is BaseTest { s_termsOfServiceAllowList = new TermsOfServiceAllowList(address(s_functionsRouter), getTermsOfServiceConfig()); } - function getRouterConfig() public view returns (bytes memory) { + function getRouterConfig() public view returns (IFunctionsRouter.Config memory) { uint32[] memory maxCallbackGasLimits = new uint32[](1); maxCallbackGasLimits[0] = type(uint32).max; - // First create the struct to get some type safety - IFunctionsRouter.Config memory routerConfig = IFunctionsRouter.Config({ - maxConsumersPerSubscription: s_maxConsumersPerSubscription, - adminFee: s_adminFee, - handleOracleFulfillmentSelector: s_handleOracleFulfillmentSelector, - maxCallbackGasLimits: maxCallbackGasLimits - }); - return - abi.encode( - routerConfig.maxConsumersPerSubscription, - routerConfig.adminFee, - routerConfig.handleOracleFulfillmentSelector, - routerConfig.maxCallbackGasLimits - ); + IFunctionsRouter.Config({ + maxConsumersPerSubscription: s_maxConsumersPerSubscription, + adminFee: s_adminFee, + handleOracleFulfillmentSelector: s_handleOracleFulfillmentSelector, + maxCallbackGasLimits: maxCallbackGasLimits + }); } function getCoordinatorConfig() public pure returns (bytes memory) { - FunctionsBilling.Config memory billingConfig = FunctionsBilling.Config({ + IFunctionsBilling.Config memory billingConfig = IFunctionsBilling.Config({ maxCallbackGasLimit: 5, feedStalenessSeconds: 5, gasOverheadAfterCallback: 5, diff --git a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol index 61073b23450..68057af47b6 100644 --- a/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol +++ b/contracts/src/v0.8/functions/tests/1_0_0/testhelpers/FunctionsClientTestHelper.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.6; -import {FunctionsRequest} from "../../../dev/1_0_0/libraries/FunctionsRequest.sol"; -import {FunctionsClient} from "../../../dev/1_0_0/FunctionsClient.sol"; import {ITermsOfServiceAllowList} from "../../../dev/1_0_0/accessControl/interfaces/ITermsOfServiceAllowList.sol"; import {IFunctionsSubscriptions} from "../../../dev/1_0_0/interfaces/IFunctionsSubscriptions.sol"; diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC5267.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC5267.sol new file mode 100644 index 00000000000..4a3282f1f20 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/IERC5267.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC5267.sol) + +pragma solidity ^0.8.0; + +interface IERC5267 { + /** + * @dev MAY be emitted to signal that the domain could have changed. + */ + event EIP712DomainChanged(); + + /** + * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 + * signature. + */ + function eip712Domain() + external + view + returns ( + bytes1 fields, + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + uint256[] memory extensions + ); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/draft-IERC6093.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/draft-IERC6093.sol new file mode 100644 index 00000000000..84ac72c7f73 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/interfaces/draft-IERC6093.sol @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** + * @dev Standard ERC20 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. + */ +interface IERC20Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC20InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC20InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. + * @param spender Address that may be allowed to operate on tokens without being their owner. + * @param allowance Amount of tokens a `spender` is allowed to operate with. + * @param needed Minimum amount required to perform a transfer. + */ + error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC20InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `spender` to be approved. Used in approvals. + * @param spender Address that may be allowed to operate on tokens without being their owner. + */ + error ERC20InvalidSpender(address spender); +} + +/** + * @dev Standard ERC721 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. + */ +interface IERC721Errors { + /** + * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. + * Used in balance queries. + * @param owner Address of the current owner of a token. + */ + error ERC721InvalidOwner(address owner); + + /** + * @dev Indicates a `tokenId` whose `owner` is the zero address. + * @param tokenId Identifier number of a token. + */ + error ERC721NonexistentToken(uint256 tokenId); + + /** + * @dev Indicates an error related to the ownership over a particular token. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param tokenId Identifier number of a token. + * @param owner Address of the current owner of a token. + */ + error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC721InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC721InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `operator`’s approval. Used in transfers. + * @param operator Address that may be allowed to operate on tokens without being their owner. + * @param tokenId Identifier number of a token. + */ + error ERC721InsufficientApproval(address operator, uint256 tokenId); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC721InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `operator` to be approved. Used in approvals. + * @param operator Address that may be allowed to operate on tokens without being their owner. + */ + error ERC721InvalidOperator(address operator); +} + +/** + * @dev Standard ERC1155 Errors + * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. + */ +interface IERC1155Errors { + /** + * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + * @param balance Current balance for the interacting account. + * @param needed Minimum amount required to perform a transfer. + * @param tokenId Identifier number of a token. + */ + error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); + + /** + * @dev Indicates a failure with the token `sender`. Used in transfers. + * @param sender Address whose tokens are being transferred. + */ + error ERC1155InvalidSender(address sender); + + /** + * @dev Indicates a failure with the token `receiver`. Used in transfers. + * @param receiver Address to which tokens are being transferred. + */ + error ERC1155InvalidReceiver(address receiver); + + /** + * @dev Indicates a failure with the `operator`’s approval. Used in transfers. + * @param operator Address that may be allowed to operate on tokens without being their owner. + * @param owner Address of the current owner of a token. + */ + error ERC1155MissingApprovalForAll(address operator, address owner); + + /** + * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. + * @param approver Address initiating an approval operation. + */ + error ERC1155InvalidApprover(address approver); + + /** + * @dev Indicates a failure with the `operator` to be approved. Used in approvals. + * @param operator Address that may be allowed to operate on tokens without being their owner. + */ + error ERC1155InvalidOperator(address operator); + + /** + * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. + * Used in batch transfers. + * @param idsLength Length of the array of token identifiers + * @param valuesLength Length of the array of token amounts + */ + error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/ERC20.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/ERC20.sol new file mode 100644 index 00000000000..89ec2152080 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/ERC20.sol @@ -0,0 +1,370 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) + +pragma solidity ^0.8.0; + +import {IERC20} from "./IERC20.sol"; +import {IERC20Metadata} from "./extensions/IERC20Metadata.sol"; +import {Context} from "../../utils/Context.sol"; +import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol"; + +/** + * @dev Implementation of the {IERC20} interface. + * + * This implementation is agnostic to the way tokens are created. This means + * that a supply mechanism has to be added in a derived contract using {_mint}. + * + * TIP: For a detailed writeup see our guide + * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How + * to implement supply mechanisms]. + * + * The default value of {decimals} is 18. To change this, you should override + * this function so it returns a different value. + * + * We have followed general OpenZeppelin Contracts guidelines: functions revert + * instead returning `false` on failure. This behavior is nonetheless + * conventional and does not conflict with the expectations of ERC20 + * applications. + * + * Additionally, an {Approval} event is emitted on calls to {transferFrom}. + * This allows applications to reconstruct the allowance for all accounts just + * by listening to said events. Other implementations of the EIP may not emit + * these events, as it isn't required by the specification. + * + * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} + * functions have been added to mitigate the well-known issues around setting + * allowances. See {IERC20-approve}. + */ +abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { + mapping(address => uint256) private _balances; + + mapping(address => mapping(address => uint256)) private _allowances; + + uint256 private _totalSupply; + + string private _name; + string private _symbol; + + /** + * @dev Indicates a failed `decreaseAllowance` request. + */ + error ERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); + + /** + * @dev Sets the values for {name} and {symbol}. + * + * All two of these values are immutable: they can only be set once during + * construction. + */ + constructor(string memory name_, string memory symbol_) { + _name = name_; + _symbol = symbol_; + } + + /** + * @dev Returns the name of the token. + */ + function name() public view virtual returns (string memory) { + return _name; + } + + /** + * @dev Returns the symbol of the token, usually a shorter version of the + * name. + */ + function symbol() public view virtual returns (string memory) { + return _symbol; + } + + /** + * @dev Returns the number of decimals used to get its user representation. + * For example, if `decimals` equals `2`, a balance of `505` tokens should + * be displayed to a user as `5.05` (`505 / 10 ** 2`). + * + * Tokens usually opt for a value of 18, imitating the relationship between + * Ether and Wei. This is the default value returned by this function, unless + * it's overridden. + * + * NOTE: This information is only used for _display_ purposes: it in + * no way affects any of the arithmetic of the contract, including + * {IERC20-balanceOf} and {IERC20-transfer}. + */ + function decimals() public view virtual returns (uint8) { + return 18; + } + + /** + * @dev See {IERC20-totalSupply}. + */ + function totalSupply() public view virtual returns (uint256) { + return _totalSupply; + } + + /** + * @dev See {IERC20-balanceOf}. + */ + function balanceOf(address account) public view virtual returns (uint256) { + return _balances[account]; + } + + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `to` cannot be the zero address. + * - the caller must have a balance of at least `value`. + */ + function transfer(address to, uint256 value) public virtual returns (bool) { + address owner = _msgSender(); + _transfer(owner, to, value); + return true; + } + + /** + * @dev See {IERC20-allowance}. + */ + function allowance(address owner, address spender) public view virtual returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev See {IERC20-approve}. + * + * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on + * `transferFrom`. This is semantically equivalent to an infinite approval. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 value) public virtual returns (bool) { + address owner = _msgSender(); + _approve(owner, spender, value); + return true; + } + + /** + * @dev See {IERC20-transferFrom}. + * + * Emits an {Approval} event indicating the updated allowance. This is not + * required by the EIP. See the note at the beginning of {ERC20}. + * + * NOTE: Does not update the allowance if the current allowance + * is the maximum `uint256`. + * + * Requirements: + * + * - `from` and `to` cannot be the zero address. + * - `from` must have a balance of at least `value`. + * - the caller must have allowance for ``from``'s tokens of at least + * `value`. + */ + function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { + address spender = _msgSender(); + _spendAllowance(from, spender, value); + _transfer(from, to, value); + return true; + } + + /** + * @dev Atomically increases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { + address owner = _msgSender(); + _approve(owner, spender, allowance(owner, spender) + addedValue); + return true; + } + + /** + * @dev Atomically decreases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `spender` must have allowance for the caller of at least + * `requestedDecrease`. + * + * NOTE: Although this function is designed to avoid double spending with {approval}, + * it can still be frontrunned, preventing any attempt of allowance reduction. + */ + function decreaseAllowance(address spender, uint256 requestedDecrease) public virtual returns (bool) { + address owner = _msgSender(); + uint256 currentAllowance = allowance(owner, spender); + if (currentAllowance < requestedDecrease) { + revert ERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); + } + unchecked { + _approve(owner, spender, currentAllowance - requestedDecrease); + } + + return true; + } + + /** + * @dev Moves a `value` amount of tokens from `from` to `to`. + * + * This internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * NOTE: This function is not virtual, {_update} should be overridden instead. + */ + function _transfer(address from, address to, uint256 value) internal { + if (from == address(0)) { + revert ERC20InvalidSender(address(0)); + } + if (to == address(0)) { + revert ERC20InvalidReceiver(address(0)); + } + _update(from, to, value); + } + + /** + * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` (or `to`) is + * the zero address. All customizations to transfers, mints, and burns should be done by overriding this function. + * + * Emits a {Transfer} event. + */ + function _update(address from, address to, uint256 value) internal virtual { + if (from == address(0)) { + // Overflow check required: The rest of the code assumes that totalSupply never overflows + _totalSupply += value; + } else { + uint256 fromBalance = _balances[from]; + if (fromBalance < value) { + revert ERC20InsufficientBalance(from, fromBalance, value); + } + unchecked { + // Overflow not possible: value <= fromBalance <= totalSupply. + _balances[from] = fromBalance - value; + } + } + + if (to == address(0)) { + unchecked { + // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. + _totalSupply -= value; + } + } else { + unchecked { + // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. + _balances[to] += value; + } + } + + emit Transfer(from, to, value); + } + + /** + * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). + * Relies on the `_update` mechanism + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * NOTE: This function is not virtual, {_update} should be overridden instead. + */ + function _mint(address account, uint256 value) internal { + if (account == address(0)) { + revert ERC20InvalidReceiver(address(0)); + } + _update(address(0), account, value); + } + + /** + * @dev Destroys a `value` amount of tokens from `account`, by transferring it to address(0). + * Relies on the `_update` mechanism. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * NOTE: This function is not virtual, {_update} should be overridden instead + */ + function _burn(address account, uint256 value) internal { + if (account == address(0)) { + revert ERC20InvalidSender(address(0)); + } + _update(account, address(0), value); + } + + /** + * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens. + * + * This internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + */ + function _approve(address owner, address spender, uint256 value) internal virtual { + _approve(owner, spender, value, true); + } + + /** + * @dev Alternative version of {_approve} with an optional flag that can enable or disable the Approval event. + * + * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by + * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any + * `Approval` event during `transferFrom` operations. + * + * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to true + * using the following override: + * ``` + * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { + * super._approve(owner, spender, value, true); + * } + * ``` + * + * Requirements are the same as {_approve}. + */ + function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { + if (owner == address(0)) { + revert ERC20InvalidApprover(address(0)); + } + if (spender == address(0)) { + revert ERC20InvalidSpender(address(0)); + } + _allowances[owner][spender] = value; + if (emitEvent) { + emit Approval(owner, spender, value); + } + } + + /** + * @dev Updates `owner` s allowance for `spender` based on spent `value`. + * + * Does not update the allowance value in case of infinite allowance. + * Revert if not enough allowance is available. + * + * Might emit an {Approval} event. + */ + function _spendAllowance(address owner, address spender, uint256 value) internal virtual { + uint256 currentAllowance = allowance(owner, spender); + if (currentAllowance != type(uint256).max) { + if (currentAllowance < value) { + revert ERC20InsufficientAllowance(spender, currentAllowance, value); + } + unchecked { + _approve(owner, spender, currentAllowance - value, false); + } + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol new file mode 100644 index 00000000000..d5ce96680c6 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20 { + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); + + /** + * @dev Returns the value of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the value of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves a `value` amount of tokens from the caller's account to `to`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address to, uint256 value) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets a `value` amount of tokens as the allowance of `spender` over the + * caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 value) external returns (bool); + + /** + * @dev Moves a `value` amount of tokens from `from` to `to` using the + * allowance mechanism. `value` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom(address from, address to, uint256 value) external returns (bool); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/ERC20Permit.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/ERC20Permit.sol new file mode 100644 index 00000000000..bdd86286f51 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/ERC20Permit.sol @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/ERC20Permit.sol) + +pragma solidity ^0.8.0; + +import {IERC20Permit} from "./IERC20Permit.sol"; +import {ERC20} from "../ERC20.sol"; +import {ECDSA} from "../../../utils/cryptography/ECDSA.sol"; +import {EIP712} from "../../../utils/cryptography/EIP712.sol"; +import {Nonces} from "../../../utils/Nonces.sol"; + +/** + * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in + * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. + * + * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by + * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't + * need to send a transaction, and thus is not required to hold Ether at all. + */ +abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712, Nonces { + // solhint-disable-next-line var-name-mixedcase + bytes32 private constant _PERMIT_TYPEHASH = + keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); + + /** + * @dev Permit deadline has expired. + */ + error ERC2612ExpiredSignature(uint256 deadline); + + /** + * @dev Mismatched signature. + */ + error ERC2612InvalidSigner(address signer, address owner); + + /** + * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. + * + * It's a good idea to use the same `name` that is defined as the ERC20 token name. + */ + constructor(string memory name) EIP712(name, "1") {} + + /** + * @dev See {IERC20Permit-permit}. + */ + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) public virtual { + if (block.timestamp > deadline) { + revert ERC2612ExpiredSignature(deadline); + } + + bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); + + bytes32 hash = _hashTypedDataV4(structHash); + + address signer = ECDSA.recover(hash, v, r, s); + if (signer != owner) { + revert ERC2612InvalidSigner(signer, owner); + } + + _approve(owner, spender, value); + } + + /** + * @dev See {IERC20Permit-nonces}. + */ + function nonces(address owner) public view virtual override(IERC20Permit, Nonces) returns (uint256) { + return super.nonces(owner); + } + + /** + * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. + */ + // solhint-disable-next-line func-name-mixedcase + function DOMAIN_SEPARATOR() external view virtual returns (bytes32) { + return _domainSeparatorV4(); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/IERC20Metadata.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/IERC20Metadata.sol new file mode 100644 index 00000000000..4db4ba20264 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/IERC20Metadata.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) + +pragma solidity ^0.8.0; + +import {IERC20} from "../IERC20.sol"; + +/** + * @dev Interface for the optional metadata functions from the ERC20 standard. + */ +interface IERC20Metadata is IERC20 { + /** + * @dev Returns the name of the token. + */ + function name() external view returns (string memory); + + /** + * @dev Returns the symbol of the token. + */ + function symbol() external view returns (string memory); + + /** + * @dev Returns the decimals places of the token. + */ + function decimals() external view returns (uint8); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/IERC20Permit.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/IERC20Permit.sol new file mode 100644 index 00000000000..89416499151 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/extensions/IERC20Permit.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in + * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. + * + * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by + * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't + * need to send a transaction, and thus is not required to hold Ether at all. + */ +interface IERC20Permit { + /** + * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, + * given ``owner``'s signed approval. + * + * IMPORTANT: The same issues {IERC20-approve} has related to transaction + * ordering also apply here. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `deadline` must be a timestamp in the future. + * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` + * over the EIP712-formatted function arguments. + * - the signature must use ``owner``'s current nonce (see {nonces}). + * + * For more information on the signature format, see the + * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP + * section]. + */ + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external; + + /** + * @dev Returns the current nonce for `owner`. This value must be + * included whenever a signature is generated for {permit}. + * + * Every successful call to {permit} increases ``owner``'s nonce by one. This + * prevents a signature from being used multiple times. + */ + function nonces(address owner) external view returns (uint256); + + /** + * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. + */ + // solhint-disable-next-line func-name-mixedcase + function DOMAIN_SEPARATOR() external view returns (bytes32); +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol new file mode 100644 index 00000000000..b5556d921aa --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/utils/SafeERC20.sol @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol) + +pragma solidity ^0.8.0; + +import {IERC20} from "../IERC20.sol"; +import {IERC20Permit} from "../extensions/IERC20Permit.sol"; +import {Address} from "../../../utils/Address.sol"; + +/** + * @title SafeERC20 + * @dev Wrappers around ERC20 operations that throw on failure (when the token + * contract returns false). Tokens that return no value (and instead revert or + * throw on failure) are also supported, non-reverting calls are assumed to be + * successful. + * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, + * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. + */ +library SafeERC20 { + using Address for address; + + /** + * @dev An operation with an ERC20 token failed. + */ + error SafeERC20FailedOperation(address token); + + /** + * @dev Indicates a failed `decreaseAllowance` request. + */ + error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); + + /** + * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, + * non-reverting calls are assumed to be successful. + */ + function safeTransfer(IERC20 token, address to, uint256 value) internal { + _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); + } + + /** + * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the + * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. + */ + function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { + _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); + } + + /** + * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, + * non-reverting calls are assumed to be successful. + */ + function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { + uint256 oldAllowance = token.allowance(address(this), spender); + forceApprove(token, spender, oldAllowance + value); + } + + /** + * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no value, + * non-reverting calls are assumed to be successful. + */ + function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { + unchecked { + uint256 currentAllowance = token.allowance(address(this), spender); + if (currentAllowance < requestedDecrease) { + revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); + } + forceApprove(token, spender, currentAllowance - requestedDecrease); + } + } + + /** + * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, + * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval + * to be set to zero before setting it to a non-zero value, such as USDT. + */ + function forceApprove(IERC20 token, address spender, uint256 value) internal { + bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); + + if (!_callOptionalReturnBool(token, approvalCall)) { + _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); + _callOptionalReturn(token, approvalCall); + } + } + + /** + * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. + * Revert on invalid signature. + */ + function safePermit( + IERC20Permit token, + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) internal { + uint256 nonceBefore = token.nonces(owner); + token.permit(owner, spender, value, deadline, v, r, s); + uint256 nonceAfter = token.nonces(owner); + if (nonceAfter != nonceBefore + 1) { + revert SafeERC20FailedOperation(address(token)); + } + } + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + */ + function _callOptionalReturn(IERC20 token, bytes memory data) private { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that + // the target address contains contract code and also asserts for success in the low-level call. + + bytes memory returndata = address(token).functionCall(data); + if (returndata.length != 0 && !abi.decode(returndata, (bool))) { + revert SafeERC20FailedOperation(address(token)); + } + } + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + * + * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. + */ + function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false + // and not revert is the subcall reverts. + + (bool success, bytes memory returndata) = address(token).call(data); + return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Nonces.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Nonces.sol new file mode 100644 index 00000000000..0f017e3edbc --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Nonces.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/** + * @dev Provides tracking nonces for addresses. Nonces will only increment. + */ +abstract contract Nonces { + /** + * @dev The nonce used for an `account` is not the expected current nonce. + */ + error InvalidAccountNonce(address account, uint256 currentNonce); + + mapping(address => uint256) private _nonces; + + /** + * @dev Returns an the next unused nonce for an address. + */ + function nonces(address owner) public view virtual returns (uint256) { + return _nonces[owner]; + } + + /** + * @dev Consumes a nonce. + * + * Returns the current value and increments nonce. + */ + function _useNonce(address owner) internal virtual returns (uint256) { + // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be + // decremented or reset. This guarantees that the nonce never overflows. + unchecked { + // It is important to do x++ and not ++x here. + return _nonces[owner]++; + } + } + + /** + * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`. + */ + function _useCheckedNonce(address owner, uint256 nonce) internal virtual returns (uint256) { + uint256 current = _useNonce(owner); + if (nonce != current) { + revert InvalidAccountNonce(owner, current); + } + return current; + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/ShortStrings.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/ShortStrings.sol new file mode 100644 index 00000000000..fc6224c8e38 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/ShortStrings.sol @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (utils/ShortStrings.sol) + +pragma solidity ^0.8.0; + +import {StorageSlot} from "./StorageSlot.sol"; + +// | string | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | +// | length | 0x BB | +type ShortString is bytes32; + +/** + * @dev This library provides functions to convert short memory strings + * into a `ShortString` type that can be used as an immutable variable. + * + * Strings of arbitrary length can be optimized using this library if + * they are short enough (up to 31 bytes) by packing them with their + * length (1 byte) in a single EVM word (32 bytes). Additionally, a + * fallback mechanism can be used for every other case. + * + * Usage example: + * + * ```solidity + * contract Named { + * using ShortStrings for *; + * + * ShortString private immutable _name; + * string private _nameFallback; + * + * constructor(string memory contractName) { + * _name = contractName.toShortStringWithFallback(_nameFallback); + * } + * + * function name() external view returns (string memory) { + * return _name.toStringWithFallback(_nameFallback); + * } + * } + * ``` + */ +library ShortStrings { + // Used as an identifier for strings longer than 31 bytes. + bytes32 private constant _FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF; + + error StringTooLong(string str); + error InvalidShortString(); + + /** + * @dev Encode a string of at most 31 chars into a `ShortString`. + * + * This will trigger a `StringTooLong` error is the input string is too long. + */ + function toShortString(string memory str) internal pure returns (ShortString) { + bytes memory bstr = bytes(str); + if (bstr.length > 31) { + revert StringTooLong(str); + } + return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length)); + } + + /** + * @dev Decode a `ShortString` back to a "normal" string. + */ + function toString(ShortString sstr) internal pure returns (string memory) { + uint256 len = byteLength(sstr); + // using `new string(len)` would work locally but is not memory safe. + string memory str = new string(32); + /// @solidity memory-safe-assembly + assembly { + mstore(str, len) + mstore(add(str, 0x20), sstr) + } + return str; + } + + /** + * @dev Return the length of a `ShortString`. + */ + function byteLength(ShortString sstr) internal pure returns (uint256) { + uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF; + if (result > 31) { + revert InvalidShortString(); + } + return result; + } + + /** + * @dev Encode a string into a `ShortString`, or write it to storage if it is too long. + */ + function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) { + if (bytes(value).length < 32) { + return toShortString(value); + } else { + StorageSlot.getStringSlot(store).value = value; + return ShortString.wrap(_FALLBACK_SENTINEL); + } + } + + /** + * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}. + */ + function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) { + if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { + return toString(value); + } else { + return store; + } + } + + /** + * @dev Return the length of a string that was encoded to `ShortString` or written to storage using {setWithFallback}. + * + * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of + * actual characters as the UTF-8 encoding of a single character can span over multiple bytes. + */ + function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) { + if (ShortString.unwrap(value) != _FALLBACK_SENTINEL) { + return byteLength(value); + } else { + return bytes(store).length; + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/StorageSlot.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/StorageSlot.sol new file mode 100644 index 00000000000..599f466e315 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/StorageSlot.sol @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol) +// This file was procedurally generated from scripts/generate/templates/StorageSlot.js. + +pragma solidity ^0.8.0; + +/** + * @dev Library for reading and writing primitive types to specific storage slots. + * + * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. + * This library helps with reading and writing to such slots without the need for inline assembly. + * + * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. + * + * Example usage to set ERC1967 implementation slot: + * ```solidity + * contract ERC1967 { + * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + * + * function _getImplementation() internal view returns (address) { + * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; + * } + * + * function _setImplementation(address newImplementation) internal { + * require(newImplementation.code.length > 0); + * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; + * } + * } + * ``` + */ +library StorageSlot { + struct AddressSlot { + address value; + } + + struct BooleanSlot { + bool value; + } + + struct Bytes32Slot { + bytes32 value; + } + + struct Uint256Slot { + uint256 value; + } + + struct StringSlot { + string value; + } + + struct BytesSlot { + bytes value; + } + + /** + * @dev Returns an `AddressSlot` with member `value` located at `slot`. + */ + function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `BooleanSlot` with member `value` located at `slot`. + */ + function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. + */ + function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Uint256Slot` with member `value` located at `slot`. + */ + function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `StringSlot` with member `value` located at `slot`. + */ + function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `StringSlot` representation of the string storage pointer `store`. + */ + function getStringSlot(string storage store) internal pure returns (StringSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := store.slot + } + } + + /** + * @dev Returns an `BytesSlot` with member `value` located at `slot`. + */ + function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`. + */ + function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) { + /// @solidity memory-safe-assembly + assembly { + r.slot := store.slot + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Strings.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Strings.sol new file mode 100644 index 00000000000..e16d66d9477 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/Strings.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) + +pragma solidity ^0.8.0; + +import {Math} from "./math/Math.sol"; +import {SignedMath} from "./math/SignedMath.sol"; + +/** + * @dev String operations. + */ +library Strings { + bytes16 private constant _SYMBOLS = "0123456789abcdef"; + uint8 private constant _ADDRESS_LENGTH = 20; + + /** + * @dev The `value` string doesn't fit in the specified `length`. + */ + error StringsInsufficientHexLength(uint256 value, uint256 length); + + /** + * @dev Converts a `uint256` to its ASCII `string` decimal representation. + */ + function toString(uint256 value) internal pure returns (string memory) { + unchecked { + uint256 length = Math.log10(value) + 1; + string memory buffer = new string(length); + uint256 ptr; + /// @solidity memory-safe-assembly + assembly { + ptr := add(buffer, add(32, length)) + } + while (true) { + ptr--; + /// @solidity memory-safe-assembly + assembly { + mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) + } + value /= 10; + if (value == 0) break; + } + return buffer; + } + } + + /** + * @dev Converts a `int256` to its ASCII `string` decimal representation. + */ + function toStringSigned(int256 value) internal pure returns (string memory) { + return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value))); + } + + /** + * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. + */ + function toHexString(uint256 value) internal pure returns (string memory) { + unchecked { + return toHexString(value, Math.log256(value) + 1); + } + } + + /** + * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. + */ + function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { + uint256 localValue = value; + bytes memory buffer = new bytes(2 * length + 2); + buffer[0] = "0"; + buffer[1] = "x"; + for (uint256 i = 2 * length + 1; i > 1; --i) { + buffer[i] = _SYMBOLS[localValue & 0xf]; + localValue >>= 4; + } + if (localValue != 0) { + revert StringsInsufficientHexLength(value, length); + } + return string(buffer); + } + + /** + * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. + */ + function toHexString(address addr) internal pure returns (string memory) { + return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); + } + + /** + * @dev Returns true if the two strings are equal. + */ + function equal(string memory a, string memory b) internal pure returns (bool) { + return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b)); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/ECDSA.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/ECDSA.sol new file mode 100644 index 00000000000..ea3bf4833f0 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/ECDSA.sol @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/ECDSA.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. + * + * These functions can be used to verify that a message was signed by the holder + * of the private keys of a given address. + */ +library ECDSA { + enum RecoverError { + NoError, + InvalidSignature, + InvalidSignatureLength, + InvalidSignatureS + } + + /** + * @dev The signature derives the `address(0)`. + */ + error ECDSAInvalidSignature(); + + /** + * @dev The signature has an invalid length. + */ + error ECDSAInvalidSignatureLength(uint256 length); + + /** + * @dev The signature has an S value that is in the upper half order. + */ + error ECDSAInvalidSignatureS(bytes32 s); + + /** + * @dev Returns the address that signed a hashed message (`hash`) with + * `signature` or error string. This address can then be used for verification purposes. + * + * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: + * this function rejects them by requiring the `s` value to be in the lower + * half order, and the `v` value to be either 27 or 28. + * + * IMPORTANT: `hash` _must_ be the result of a hash operation for the + * verification to be secure: it is possible to craft signatures that + * recover to arbitrary addresses for non-hashed data. A safe way to ensure + * this is by receiving a hash of the original message (which may otherwise + * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. + * + * Documentation for signature generation: + * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] + * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] + */ + function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) { + if (signature.length == 65) { + bytes32 r; + bytes32 s; + uint8 v; + // ecrecover takes the signature parameters, and the only way to get them + // currently is to use assembly. + /// @solidity memory-safe-assembly + assembly { + r := mload(add(signature, 0x20)) + s := mload(add(signature, 0x40)) + v := byte(0, mload(add(signature, 0x60))) + } + return tryRecover(hash, v, r, s); + } else { + return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length)); + } + } + + /** + * @dev Returns the address that signed a hashed message (`hash`) with + * `signature`. This address can then be used for verification purposes. + * + * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures: + * this function rejects them by requiring the `s` value to be in the lower + * half order, and the `v` value to be either 27 or 28. + * + * IMPORTANT: `hash` _must_ be the result of a hash operation for the + * verification to be secure: it is possible to craft signatures that + * recover to arbitrary addresses for non-hashed data. A safe way to ensure + * this is by receiving a hash of the original message (which may otherwise + * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it. + */ + function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { + (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature); + _throwError(error, errorArg); + return recovered; + } + + /** + * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. + * + * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] + */ + function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) { + unchecked { + bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); + // We do not check for an overflow here since the shift operation results in 0 or 1. + uint8 v = uint8((uint256(vs) >> 255) + 27); + return tryRecover(hash, v, r, s); + } + } + + /** + * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. + */ + function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { + (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs); + _throwError(error, errorArg); + return recovered; + } + + /** + * @dev Overload of {ECDSA-tryRecover} that receives the `v`, + * `r` and `s` signature fields separately. + */ + function tryRecover( + bytes32 hash, + uint8 v, + bytes32 r, + bytes32 s + ) internal pure returns (address, RecoverError, bytes32) { + // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature + // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines + // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most + // signatures from current libraries generate a unique signature with an s-value in the lower half order. + // + // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value + // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or + // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept + // these malleable signatures as well. + if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { + return (address(0), RecoverError.InvalidSignatureS, s); + } + + // If the signature is valid (and not malleable), return the signer address + address signer = ecrecover(hash, v, r, s); + if (signer == address(0)) { + return (address(0), RecoverError.InvalidSignature, bytes32(0)); + } + + return (signer, RecoverError.NoError, bytes32(0)); + } + + /** + * @dev Overload of {ECDSA-recover} that receives the `v`, + * `r` and `s` signature fields separately. + */ + function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { + (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s); + _throwError(error, errorArg); + return recovered; + } + + /** + * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided. + */ + function _throwError(RecoverError error, bytes32 errorArg) private pure { + if (error == RecoverError.NoError) { + return; // no error: do nothing + } else if (error == RecoverError.InvalidSignature) { + revert ECDSAInvalidSignature(); + } else if (error == RecoverError.InvalidSignatureLength) { + revert ECDSAInvalidSignatureLength(uint256(errorArg)); + } else if (error == RecoverError.InvalidSignatureS) { + revert ECDSAInvalidSignatureS(errorArg); + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/EIP712.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/EIP712.sol new file mode 100644 index 00000000000..bfaf8bd6576 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/EIP712.sol @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol) + +pragma solidity ^0.8.0; + +import {MessageHashUtils} from "./MessageHashUtils.sol"; +import {ShortStrings, ShortString} from "../ShortStrings.sol"; +import {IERC5267} from "../../interfaces/IERC5267.sol"; + +/** + * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. + * + * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose + * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract + * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to + * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`. + * + * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding + * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA + * ({_hashTypedDataV4}). + * + * The implementation of the domain separator was designed to be as efficient as possible while still properly updating + * the chain id to protect against replay attacks on an eventual fork of the chain. + * + * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method + * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. + * + * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain + * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the + * separator from the immutable values, which is cheaper than accessing a cached version in cold storage. + * + * @custom:oz-upgrades-unsafe-allow state-variable-immutable + */ +abstract contract EIP712 is IERC5267 { + using ShortStrings for *; + + bytes32 private constant _TYPE_HASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + + // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to + // invalidate the cached domain separator if the chain id changes. + bytes32 private immutable _cachedDomainSeparator; + uint256 private immutable _cachedChainId; + address private immutable _cachedThis; + + bytes32 private immutable _hashedName; + bytes32 private immutable _hashedVersion; + + ShortString private immutable _name; + ShortString private immutable _version; + string private _nameFallback; + string private _versionFallback; + + /** + * @dev Initializes the domain separator and parameter caches. + * + * The meaning of `name` and `version` is specified in + * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: + * + * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. + * - `version`: the current major version of the signing domain. + * + * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart + * contract upgrade]. + */ + constructor(string memory name, string memory version) { + _name = name.toShortStringWithFallback(_nameFallback); + _version = version.toShortStringWithFallback(_versionFallback); + _hashedName = keccak256(bytes(name)); + _hashedVersion = keccak256(bytes(version)); + + _cachedChainId = block.chainid; + _cachedDomainSeparator = _buildDomainSeparator(); + _cachedThis = address(this); + } + + /** + * @dev Returns the domain separator for the current chain. + */ + function _domainSeparatorV4() internal view returns (bytes32) { + if (address(this) == _cachedThis && block.chainid == _cachedChainId) { + return _cachedDomainSeparator; + } else { + return _buildDomainSeparator(); + } + } + + function _buildDomainSeparator() private view returns (bytes32) { + return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); + } + + /** + * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this + * function returns the hash of the fully encoded EIP712 message for this domain. + * + * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: + * + * ```solidity + * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( + * keccak256("Mail(address to,string contents)"), + * mailTo, + * keccak256(bytes(mailContents)) + * ))); + * address signer = ECDSA.recover(digest, signature); + * ``` + */ + function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { + return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash); + } + + /** + * @dev See {IERC-5267}. + */ + function eip712Domain() + public + view + virtual + returns ( + bytes1 fields, + string memory name, + string memory version, + uint256 chainId, + address verifyingContract, + bytes32 salt, + uint256[] memory extensions + ) + { + return ( + hex"0f", // 01111 + _EIP712Name(), + _EIP712Version(), + block.chainid, + address(this), + bytes32(0), + new uint256[](0) + ); + } + + /** + * @dev The name parameter for the EIP712 domain. + * + * NOTE: By default this function reads _name which is an immutable value. + * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). + */ + // solhint-disable-next-line func-name-mixedcase + function _EIP712Name() internal view returns (string memory) { + return _name.toStringWithFallback(_nameFallback); + } + + /** + * @dev The version parameter for the EIP712 domain. + * + * NOTE: By default this function reads _version which is an immutable value. + * It only reads from storage if necessary (in case the value is too large to fit in a ShortString). + */ + // solhint-disable-next-line func-name-mixedcase + function _EIP712Version() internal view returns (string memory) { + return _version.toStringWithFallback(_versionFallback); + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/MessageHashUtils.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/MessageHashUtils.sol new file mode 100644 index 00000000000..fa0730e35bd --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/cryptography/MessageHashUtils.sol @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +import {Strings} from "../Strings.sol"; + +/** + * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. + * + * The library provides methods for generating a hash of a message that conforms to the + * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] + * specifications. + */ +library MessageHashUtils { + /** + * @dev Returns the keccak256 digest of an EIP-191 signed data with version + * `0x45` (`personal_sign` messages). + * + * The digest is calculated by prefixing a bytes32 `messageHash` with + * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the + * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. + * + * NOTE: The `hash` parameter is intended to be the result of hashing a raw message with + * keccak256, although any bytes32 value can be safely used because the final digest will + * be re-hashed. + * + * See {ECDSA-recover}. + */ + function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) { + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash + mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix + digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20) + } + } + + /** + * @dev Returns the keccak256 digest of an EIP-191 signed data with version + * `0x45` (`personal_sign` messages). + * + * The digest is calculated by prefixing an arbitrary `message` with + * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the + * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method. + * + * See {ECDSA-recover}. + */ + function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32 digest) { + return keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message)); + } + + /** + * @dev Returns the keccak256 digest of an EIP-191 signed data with version + * `0x00` (data with intended validator). + * + * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended + * `validator` address. Then hashing the result. + * + * See {ECDSA-recover}. + */ + function toDataWithIntendedValidatorHash( + address validator, + bytes memory data + ) internal pure returns (bytes32 digest) { + return keccak256(abi.encodePacked(hex"19_00", validator, data)); + } + + /** + * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`). + * + * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with + * `\x19\x01` and hashing the result. It corresponds to the hash signed by the + * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. + * + * See {ECDSA-recover}. + */ + function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { + /// @solidity memory-safe-assembly + assembly { + let ptr := mload(0x40) + mstore(ptr, hex"19_01") + mstore(add(ptr, 0x02), domainSeparator) + mstore(add(ptr, 0x22), structHash) + digest := keccak256(ptr, 0x42) + } + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/Math.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/Math.sol new file mode 100644 index 00000000000..e429e5db781 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/Math.sol @@ -0,0 +1,414 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Standard math utilities missing in the Solidity language. + */ +library Math { + /** + * @dev Muldiv operation overflow. + */ + error MathOverflowedMulDiv(); + + enum Rounding { + Floor, // Toward negative infinity + Ceil, // Toward positive infinity + Trunc, // Toward zero + Expand // Away from zero + } + + /** + * @dev Returns the addition of two unsigned integers, with an overflow flag. + */ + function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { + unchecked { + uint256 c = a + b; + if (c < a) return (false, 0); + return (true, c); + } + } + + /** + * @dev Returns the subtraction of two unsigned integers, with an overflow flag. + */ + function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { + unchecked { + if (b > a) return (false, 0); + return (true, a - b); + } + } + + /** + * @dev Returns the multiplication of two unsigned integers, with an overflow flag. + */ + function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { + unchecked { + // Gas optimization: this is cheaper than requiring 'a' not being zero, but the + // benefit is lost if 'b' is also tested. + // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 + if (a == 0) return (true, 0); + uint256 c = a * b; + if (c / a != b) return (false, 0); + return (true, c); + } + } + + /** + * @dev Returns the division of two unsigned integers, with a division by zero flag. + */ + function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { + unchecked { + if (b == 0) return (false, 0); + return (true, a / b); + } + } + + /** + * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. + */ + function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { + unchecked { + if (b == 0) return (false, 0); + return (true, a % b); + } + } + + /** + * @dev Returns the largest of two numbers. + */ + function max(uint256 a, uint256 b) internal pure returns (uint256) { + return a > b ? a : b; + } + + /** + * @dev Returns the smallest of two numbers. + */ + function min(uint256 a, uint256 b) internal pure returns (uint256) { + return a < b ? a : b; + } + + /** + * @dev Returns the average of two numbers. The result is rounded towards + * zero. + */ + function average(uint256 a, uint256 b) internal pure returns (uint256) { + // (a + b) / 2 can overflow. + return (a & b) + (a ^ b) / 2; + } + + /** + * @dev Returns the ceiling of the division of two numbers. + * + * This differs from standard division with `/` in that it rounds towards infinity instead + * of rounding towards zero. + */ + function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { + if (b == 0) { + // Guarantee the same behavior as in a regular Solidity division. + return a / b; + } + + // (a + b - 1) / b can overflow on addition, so we distribute. + return a == 0 ? 0 : (a - 1) / b + 1; + } + + /** + * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 + * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) + * with further edits by Uniswap Labs also under MIT license. + */ + function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { + unchecked { + // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use + // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 + // variables such that product = prod1 * 2^256 + prod0. + uint256 prod0 = x * y; // Least significant 256 bits of the product + uint256 prod1; // Most significant 256 bits of the product + assembly { + let mm := mulmod(x, y, not(0)) + prod1 := sub(sub(mm, prod0), lt(mm, prod0)) + } + + // Handle non-overflow cases, 256 by 256 division. + if (prod1 == 0) { + // Solidity will revert if denominator == 0, unlike the div opcode on its own. + // The surrounding unchecked block does not change this fact. + // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. + return prod0 / denominator; + } + + // Make sure the result is less than 2^256. Also prevents denominator == 0. + if (denominator <= prod1) { + revert MathOverflowedMulDiv(); + } + + /////////////////////////////////////////////// + // 512 by 256 division. + /////////////////////////////////////////////// + + // Make division exact by subtracting the remainder from [prod1 prod0]. + uint256 remainder; + assembly { + // Compute remainder using mulmod. + remainder := mulmod(x, y, denominator) + + // Subtract 256 bit number from 512 bit number. + prod1 := sub(prod1, gt(remainder, prod0)) + prod0 := sub(prod0, remainder) + } + + // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. + // See https://cs.stackexchange.com/q/138556/92363. + + uint256 twos = denominator & (0 - denominator); + assembly { + // Divide denominator by twos. + denominator := div(denominator, twos) + + // Divide [prod1 prod0] by twos. + prod0 := div(prod0, twos) + + // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. + twos := add(div(sub(0, twos), twos), 1) + } + + // Shift in bits from prod1 into prod0. + prod0 |= prod1 * twos; + + // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such + // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for + // four bits. That is, denominator * inv = 1 mod 2^4. + uint256 inverse = (3 * denominator) ^ 2; + + // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works + // in modular arithmetic, doubling the correct bits in each step. + inverse *= 2 - denominator * inverse; // inverse mod 2^8 + inverse *= 2 - denominator * inverse; // inverse mod 2^16 + inverse *= 2 - denominator * inverse; // inverse mod 2^32 + inverse *= 2 - denominator * inverse; // inverse mod 2^64 + inverse *= 2 - denominator * inverse; // inverse mod 2^128 + inverse *= 2 - denominator * inverse; // inverse mod 2^256 + + // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. + // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is + // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 + // is no longer required. + result = prod0 * inverse; + return result; + } + } + + /** + * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. + */ + function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { + uint256 result = mulDiv(x, y, denominator); + if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) { + result += 1; + } + return result; + } + + /** + * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded + * towards zero. + * + * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). + */ + function sqrt(uint256 a) internal pure returns (uint256) { + if (a == 0) { + return 0; + } + + // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. + // + // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have + // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. + // + // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` + // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` + // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` + // + // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. + uint256 result = 1 << (log2(a) >> 1); + + // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, + // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at + // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision + // into the expected uint128 result. + unchecked { + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + result = (result + a / result) >> 1; + return min(result, a / result); + } + } + + /** + * @notice Calculates sqrt(a), following the selected rounding direction. + */ + function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = sqrt(a); + return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0); + } + } + + /** + * @dev Return the log in base 2 of a positive value rounded towards zero. + * Returns 0 if given 0. + */ + function log2(uint256 value) internal pure returns (uint256) { + uint256 result = 0; + unchecked { + if (value >> 128 > 0) { + value >>= 128; + result += 128; + } + if (value >> 64 > 0) { + value >>= 64; + result += 64; + } + if (value >> 32 > 0) { + value >>= 32; + result += 32; + } + if (value >> 16 > 0) { + value >>= 16; + result += 16; + } + if (value >> 8 > 0) { + value >>= 8; + result += 8; + } + if (value >> 4 > 0) { + value >>= 4; + result += 4; + } + if (value >> 2 > 0) { + value >>= 2; + result += 2; + } + if (value >> 1 > 0) { + result += 1; + } + } + return result; + } + + /** + * @dev Return the log in base 2, following the selected rounding direction, of a positive value. + * Returns 0 if given 0. + */ + function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = log2(value); + return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0); + } + } + + /** + * @dev Return the log in base 10 of a positive value rounded towards zero. + * Returns 0 if given 0. + */ + function log10(uint256 value) internal pure returns (uint256) { + uint256 result = 0; + unchecked { + if (value >= 10 ** 64) { + value /= 10 ** 64; + result += 64; + } + if (value >= 10 ** 32) { + value /= 10 ** 32; + result += 32; + } + if (value >= 10 ** 16) { + value /= 10 ** 16; + result += 16; + } + if (value >= 10 ** 8) { + value /= 10 ** 8; + result += 8; + } + if (value >= 10 ** 4) { + value /= 10 ** 4; + result += 4; + } + if (value >= 10 ** 2) { + value /= 10 ** 2; + result += 2; + } + if (value >= 10 ** 1) { + result += 1; + } + } + return result; + } + + /** + * @dev Return the log in base 10, following the selected rounding direction, of a positive value. + * Returns 0 if given 0. + */ + function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = log10(value); + return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0); + } + } + + /** + * @dev Return the log in base 256 of a positive value rounded towards zero. + * Returns 0 if given 0. + * + * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. + */ + function log256(uint256 value) internal pure returns (uint256) { + uint256 result = 0; + unchecked { + if (value >> 128 > 0) { + value >>= 128; + result += 16; + } + if (value >> 64 > 0) { + value >>= 64; + result += 8; + } + if (value >> 32 > 0) { + value >>= 32; + result += 4; + } + if (value >> 16 > 0) { + value >>= 16; + result += 2; + } + if (value >> 8 > 0) { + result += 1; + } + } + return result; + } + + /** + * @dev Return the log in base 256, following the selected rounding direction, of a positive value. + * Returns 0 if given 0. + */ + function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { + unchecked { + uint256 result = log256(value); + return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0); + } + } + + /** + * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers. + */ + function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) { + return uint8(rounding) % 2 == 1; + } +} diff --git a/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SignedMath.sol b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SignedMath.sol new file mode 100644 index 00000000000..93524bb79c0 --- /dev/null +++ b/contracts/src/v0.8/vendor/openzeppelin-solidity/v4.8.0/contracts/utils/math/SignedMath.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Standard signed math utilities missing in the Solidity language. + */ +library SignedMath { + /** + * @dev Returns the largest of two signed numbers. + */ + function max(int256 a, int256 b) internal pure returns (int256) { + return a > b ? a : b; + } + + /** + * @dev Returns the smallest of two signed numbers. + */ + function min(int256 a, int256 b) internal pure returns (int256) { + return a < b ? a : b; + } + + /** + * @dev Returns the average of two signed numbers without overflow. + * The result is rounded towards zero. + */ + function average(int256 a, int256 b) internal pure returns (int256) { + // Formula from the book "Hacker's Delight" + int256 x = (a & b) + ((a ^ b) >> 1); + return x + (int256(uint256(x) >> 255) & (a ^ b)); + } + + /** + * @dev Returns the absolute unsigned value of a signed value. + */ + function abs(int256 n) internal pure returns (uint256) { + unchecked { + // must be unchecked in order to support `n = type(int256).min` + return uint256(n >= 0 ? n : -n); + } + } +} diff --git a/contracts/test/v0.8/functions/v1/FunctionsRouter.test.ts b/contracts/test/v0.8/functions/v1/FunctionsRouter.test.ts index 4f1031ee7d8..bba8d8f7dd7 100644 --- a/contracts/test/v0.8/functions/v1/FunctionsRouter.test.ts +++ b/contracts/test/v0.8/functions/v1/FunctionsRouter.test.ts @@ -21,12 +21,14 @@ describe('Functions Router - Request lifecycle', () => { }) it('#config', async () => { const config = await contracts.router.getConfig() - expect(config[0]).to.be.equal(functionsRouterConfig.maxConsumers) - expect(config[1]).to.be.equal(functionsRouterConfig.adminFee) - expect(config[2]).to.be.equal( + expect(config.maxConsumersPerSubscription).to.be.equal( + functionsRouterConfig.maxConsumersPerSubscription, + ) + expect(config.adminFee).to.be.equal(functionsRouterConfig.adminFee) + expect(config.handleOracleFulfillmentSelector).to.be.equal( functionsRouterConfig.handleOracleFulfillmentSelector, ) - expect(config[3].toString()).to.be.equal( + expect(config.maxCallbackGasLimits.toString()).to.be.equal( functionsRouterConfig.maxCallbackGasLimits.toString(), ) }) diff --git a/contracts/test/v0.8/functions/v1/RouterBase.test.ts b/contracts/test/v0.8/functions/v1/RouterBase.test.ts index 712894742be..2a094d1148f 100644 --- a/contracts/test/v0.8/functions/v1/RouterBase.test.ts +++ b/contracts/test/v0.8/functions/v1/RouterBase.test.ts @@ -61,12 +61,20 @@ describe('FunctionsRouter - Base', () => { it('Owner can update config of the Router', async () => { const beforeConfig = await contracts.router.getConfig() - await expect( contracts.router.proposeConfigUpdateSelf( ethers.utils.defaultAbiCoder.encode( - ['uint16', 'uint96', 'bytes4', 'uint32[]'], - [2000, 1, 0x0ca76175, [300_000, 500_000]], + contracts.router.interface.events[ + 'ConfigChanged((uint16,uint96,bytes4,uint32[]))' + ].inputs, + [ + { + maxConsumersPerSubscription: 2000, + adminFee: 1, + handleOracleFulfillmentSelector: 0x0ca76175, + maxCallbackGasLimits: [300_000, 500_000], + }, + ], ), ), ).to.emit(contracts.router, 'ConfigProposed') @@ -117,7 +125,9 @@ describe('FunctionsRouter - Base', () => { it('returns the config set on the Router', async () => { const config = await contracts.router.connect(roles.stranger).getConfig() - expect(config[0]).to.equal(functionsRouterConfig.maxConsumers) + expect(config[0]).to.equal( + functionsRouterConfig.maxConsumersPerSubscription, + ) expect(config[1]).to.equal(functionsRouterConfig.adminFee) expect(config[2]).to.equal( functionsRouterConfig.handleOracleFulfillmentSelector, @@ -271,67 +281,69 @@ describe('FunctionsRouter - Base', () => { }) }) - describe('Timelock', () => { - it('prevents applying timelock updates', async () => { - await contracts.router.proposeTimelockBlocks(5) - await contracts.router.updateTimelockBlocks() - await contracts.router.proposeTimelockBlocks(6) - await expect(contracts.router.updateTimelockBlocks()).to.be.revertedWith( - 'TimelockInEffect', - ) - }) + // TODO: disabled in anticipation of MCM - it('prevents applying config updates', async () => { - await contracts.router.proposeTimelockBlocks(5) - await contracts.router.updateTimelockBlocks() + // describe('Timelock', () => { + // it('prevents applying timelock updates', async () => { + // await contracts.router.proposeTimelockBlocks(5) + // await contracts.router.updateTimelockBlocks() + // await contracts.router.proposeTimelockBlocks(6) + // await expect(contracts.router.updateTimelockBlocks()).to.be.revertedWith( + // 'TimelockInEffect', + // ) + // }) - await contracts.router.proposeConfigUpdate( - ids.routerId, - ethers.utils.defaultAbiCoder.encode( - ['uint16', 'uint96', 'bytes4', 'uint32[]'], - [2000, 1, 0x0ca76175, [300_000, 500_000]], - ), - ) - await expect( - contracts.router.updateConfig(ids.routerId), - ).to.be.revertedWith('TimelockInEffect') - }) + // it('prevents applying config updates', async () => { + // await contracts.router.proposeTimelockBlocks(5) + // await contracts.router.updateTimelockBlocks() - it('prevents applying contract updates', async () => { - await contracts.router.proposeTimelockBlocks(5) - await contracts.router.updateTimelockBlocks() + // await contracts.router.proposeConfigUpdate( + // ids.routerId, + // ethers.utils.defaultAbiCoder.encode( + // ['uint16', 'uint96', 'bytes4', 'uint32[]'], + // [2000, 1, 0x0ca76175, [300_000, 500_000]], + // ), + // ) + // await expect( + // contracts.router.updateConfig(ids.routerId), + // ).to.be.revertedWith('TimelockInEffect') + // }) - const coordinator2 = await factories.functionsCoordinatorFactory - .connect(roles.defaultAccount) - .deploy( - contracts.router.address, - ethers.utils.defaultAbiCoder.encode( - [ - 'uint32', - 'uint32', - 'uint32', - 'uint32', - 'int256', - 'uint32', - 'uint96', - 'uint16', - 'uint256', - ], - [...Object.values(coordinatorConfig)], - ), - contracts.mockLinkEth.address, - ) + // it('prevents applying contract updates', async () => { + // await contracts.router.proposeTimelockBlocks(5) + // await contracts.router.updateTimelockBlocks() - await contracts.router.proposeContractsUpdate( - [ids.donId2], - [coordinator2.address], - ) + // const coordinator2 = await factories.functionsCoordinatorFactory + // .connect(roles.defaultAccount) + // .deploy( + // contracts.router.address, + // ethers.utils.defaultAbiCoder.encode( + // [ + // 'uint32', + // 'uint32', + // 'uint32', + // 'uint32', + // 'int256', + // 'uint32', + // 'uint96', + // 'uint16', + // 'uint256', + // ], + // [...Object.values(coordinatorConfig)], + // ), + // contracts.mockLinkEth.address, + // ) - await expect(contracts.router.updateContracts()).to.be.revertedWith( - 'TimelockInEffect', - ) - }) - }) + // await contracts.router.proposeContractsUpdate( + // [ids.donId2], + // [coordinator2.address], + // ) + + // await expect(contracts.router.updateContracts()).to.be.revertedWith( + // 'TimelockInEffect', + // ) + // }) + // }) describe('Emergency Pause', () => { it('has paused state visible', async () => { diff --git a/contracts/test/v0.8/functions/v1/utils.ts b/contracts/test/v0.8/functions/v1/utils.ts index 8eddd04029a..e945d96c49f 100644 --- a/contracts/test/v0.8/functions/v1/utils.ts +++ b/contracts/test/v0.8/functions/v1/utils.ts @@ -58,13 +58,13 @@ export const encodeReport = ( } export type FunctionsRouterConfig = { - maxConsumers: number + maxConsumersPerSubscription: number adminFee: number handleOracleFulfillmentSelector: string maxCallbackGasLimits: number[] } export const functionsRouterConfig: FunctionsRouterConfig = { - maxConsumers: 100, + maxConsumersPerSubscription: 100, adminFee: 0, handleOracleFulfillmentSelector: '0x0ca76175', maxCallbackGasLimits: [300_000, 500_000, 1_000_000], @@ -226,10 +226,10 @@ export function getSetupFactory(): () => { 0, linkEthRate, ) - const routerConfigBytes = ethers.utils.defaultAbiCoder.encode( - ['uint16', 'uint96', 'bytes4', 'uint32[]'], - [...Object.values(functionsRouterConfig)], - ) + // const routerConfigBytes = ethers.utils.defaultAbiCoder.encode( + // ['uint16', 'uint96', 'bytes4', 'uint32[]'], + // [...Object.values(functionsRouterConfig)], + // ) const startingTimelockBlocks = 0 const maxTimelockBlocks = 20 const router = await factories.functionsRouterFactory @@ -238,7 +238,7 @@ export function getSetupFactory(): () => { startingTimelockBlocks, maxTimelockBlocks, linkToken.address, - routerConfigBytes, + functionsRouterConfig, ) const coordinatorConfigBytes = ethers.utils.defaultAbiCoder.encode( [ diff --git a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go index 0cff7b99918..ffb047edd01 100644 --- a/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go +++ b/core/gethwrappers/functions/generated/functions_coordinator/functions_coordinator.go @@ -44,6 +44,18 @@ type FunctionsResponseCommitment struct { GasOverheadAfterCallback *big.Int } +type IFunctionsBillingConfig struct { + MaxCallbackGasLimit uint32 + FeedStalenessSeconds uint32 + GasOverheadBeforeCallback uint32 + GasOverheadAfterCallback uint32 + RequestTimeoutSeconds uint32 + DonFee *big.Int + MaxSupportedRequestDataVersion uint16 + FulfillmentGasPriceOverEstimationBP *big.Int + FallbackNativePerUnitLink *big.Int +} + type IFunctionsBillingRequestBilling struct { SubscriptionId uint64 Client common.Address @@ -64,8 +76,8 @@ type IFunctionsCoordinatorRequest struct { } var FunctionsCoordinatorMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoTransmittersSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CommitmentDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint80\",\"name\":\"donFee\",\"type\":\"uint80\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"int256\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"callbackGasLimit\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"commitment\",\"type\":\"bytes\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"}],\"name\":\"deleteNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllNodePublicKeys\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint80\",\"name\":\"donFee\",\"type\":\"uint80\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"address\",\"name\":\"linkPriceFeed\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"expectedGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"}],\"internalType\":\"structIFunctionsBilling.RequestBilling\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"getDONFee\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeedData\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"}],\"internalType\":\"structIFunctionsCoordinator.Request\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"sendRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"uint40\",\"name\":\"timeoutTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint80\",\"name\":\"donFee\",\"type\":\"uint80\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"}],\"name\":\"setNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c06040523480156200001157600080fd5b50604051620059e7380380620059e7833981016040819052620000349162000458565b828282828260013380600081620000925760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c557620000c5816200014a565b50505015156080526001600160a01b038216620000f557604051632530e88560e11b815260040160405180910390fd5b6001600160a01b03821660a0526200010d81620001f5565b5050600c80546001600160a01b039092166c01000000000000000000000000026001600160601b03909216919091179055506200062a9350505050565b336001600160a01b03821603620001a45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000089565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008060008060008060008060008980602001905181019062000219919062000568565b9850985098509850985098509850985098506000811362000251576040516321ea67b360e11b81526004810182905260240162000089565b604080516101208101825263ffffffff808c168083528b8216602084018190528b83168486018190528b841660608601819052938b16608086018190526001600160501b038b1660a0870181905261ffff8b1660c0880181905260e088018b905261010090970189905260088054600160f01b9098026001600160f01b03600160a01b909302600160a01b600160f01b0319600160801b90950294909416600160801b600160f01b03196c0100000000000000000000000090990263ffffffff60601b196801000000000000000090970296909616600160401b600160801b03196401000000009098026001600160401b0319909b1690981799909917959095169590951792909217949094169490941792909217929092161790556009839055600a829055517f3332571032ee658b30d567e63b2443e9d921162625e0f3fe86968a586c1a090f9062000411908b908b908b908b908b908b908b908b908b9063ffffffff998a1681529789166020890152958816604088015293871660608701529190951660808501526001600160501b039490941660a084015261ffff9390931660c083015260e08201929092526101008101919091526101200190565b60405180910390a150505050505050505050565b80516001600160a01b03811681146200043d57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b6000806000606084860312156200046e57600080fd5b620004798462000425565b602085810151919450906001600160401b03808211156200049957600080fd5b818701915087601f830112620004ae57600080fd5b815181811115620004c357620004c362000442565b604051601f8201601f19908116603f01168101908382118183101715620004ee57620004ee62000442565b816040528281528a868487010111156200050757600080fd5b600093505b828410156200052b57848401860151818501870152928501926200050c565b60008684830101528097505050505050506200054a6040850162000425565b90509250925092565b805163ffffffff811681146200043d57600080fd5b60008060008060008060008060006101208a8c0312156200058857600080fd5b620005938a62000553565b9850620005a360208b0162000553565b9750620005b360408b0162000553565b9650620005c360608b0162000553565b9550620005d360808b0162000553565b60a08b01519095506001600160501b0381168114620005f157600080fd5b60c08b015190945061ffff811681146200060a57600080fd5b8093505060e08a015191506101008a015190509295985092959850929598565b60805160a051615366620006816000396000818161068601528181610abd01528181610ee001528181610fbe0152818161183901528181611ad3015281816130aa01526139080152600061120a01526153666000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c806381ff7048116100ee578063b1dc65a411610097578063d227d24511610071578063d227d24514610517578063d328a91e1461052a578063e3d0e71214610532578063f2fde38b1461054557600080fd5b8063b1dc65a4146103e6578063bdd7e880146103f9578063c3f909d41461041957600080fd5b80638da5cb5b116100c85780638da5cb5b14610388578063af1296d3146103b0578063afcb95d7146103c657600080fd5b806381ff7048146102e557806385b214cf146103525780638cc6acce1461037557600080fd5b806366316d8d11610150578063807560311161012a57806380756031146102b557806381411834146102c857806381f1b938146102dd57600080fd5b806366316d8d1461028757806379ba50971461029a5780637f15e166146102a257600080fd5b806326ceabac1161018157806326ceabac146102395780632a905ccc1461024c578063533989871461027157600080fd5b8063083a5466146101a85780630e7ada39146101bd578063181f5a77146101f0575b600080fd5b6101bb6101b6366004613b82565b610558565b005b6101d06101cb366004613d8c565b6105ad565b60405169ffffffffffffffffffff90911681526020015b60405180910390f35b61022c6040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e302e300000000081525081565b6040516101e79190613ec1565b6101bb610247366004613edb565b6105db565b610254610681565b6040516bffffffffffffffffffffffff90911681526020016101e7565b61027961073f565b6040516101e7929190613f49565b6101bb610295366004613fd9565b6109c3565b6101bb610b7d565b6101bb6102b0366004613b82565b610c7f565b6101bb6102c3366004614012565b610ccf565b6102d0610d86565b6040516101e79190614067565b61022c610df5565b61032f60015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff9485168152939092166020840152908201526060016101e7565b61036561036036600461407a565b610ec6565b60405190151581526020016101e7565b6101bb610383366004614093565b610fa6565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101e7565b6103b861101e565b6040519081526020016101e7565b6040805160018152600060208201819052918101919091526060016101e7565b6101bb6103f4366004614115565b611111565b61040c6104073660046141cc565b6117c8565b6040516101e7919061432e565b600854600954600a54600c546040805163ffffffff80871682526401000000008704811660208301526801000000000000000087048116928201929092526c01000000000000000000000000808704831660608301527001000000000000000000000000000000008704909216608082015274010000000000000000000000000000000000000000860469ffffffffffffffffffff1660a08201527e0100000000000000000000000000000000000000000000000000000000000090950461ffff1660c086015260e08501939093526101008401919091520473ffffffffffffffffffffffffffffffffffffffff16610120820152610140016101e7565b61025461052536600461433d565b611acf565b61022c611c9b565b6101bb610540366004614456565b611cf2565b6101bb610553366004613edb565b61271e565b61056061272f565b600081900361059b576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f6105a88284836145c4565b505050565b60085474010000000000000000000000000000000000000000900469ffffffffffffffffffff165b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061061957503373ffffffffffffffffffffffffffffffffffffffff821614155b15610650576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600e6020526040812061067e91613ac7565b50565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c3f909d46040518163ffffffff1660e01b8152600401600060405180830381865afa1580156106ef573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526107359190810190614705565b5090949350505050565b606080600060068054806020026020016040519081016040528092919081815260200182805480156107a757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161077c575b505050505090506000815167ffffffffffffffff8111156107ca576107ca613bc4565b6040519080825280602002602001820160405280156107fd57816020015b60608152602001906001900390816107e85790505b50905060005b82518110156109b957600e600084838151811061082257610822614800565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805461086f90614523565b90506000036108aa576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e60008483815181106108c0576108c0614800565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805461090d90614523565b80601f016020809104026020016040519081016040528092919081815260200182805461093990614523565b80156109865780601f1061095b57610100808354040283529160200191610986565b820191906000526020600020905b81548152906001019060200180831161096957829003601f168201915b505050505082828151811061099d5761099d614800565b6020026020010181905250806109b29061485e565b9050610803565b5090939092509050565b6109cb6127b2565b806bffffffffffffffffffffffff16600003610a015750336000908152600b60205260409020546bffffffffffffffffffffffff165b336000908152600b60205260409020546bffffffffffffffffffffffff80831691161015610a5b576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604081208054839290610a889084906bffffffffffffffffffffffff16614896565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506000610adf7f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85811660048301526bffffffffffffffffffffffff85166024830152919250908216906366316d8d90604401600060405180830381600087803b158015610b6057600080fd5b505af1158015610b74573d6000803e3d6000fd5b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610c8761272f565b6000819003610cc2576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105a88284836145c4565b60005473ffffffffffffffffffffffffffffffffffffffff16331480610d1a5750610cf933612943565b8015610d1a57503373ffffffffffffffffffffffffffffffffffffffff8416145b610d50576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152600e60205260409020610d808284836145c4565b50505050565b60606006805480602002602001604051908101604052809291908181526020018280548015610deb57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610dc0575b5050505050905090565b6060600f8054610e0490614523565b9050600003610e3f576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f8054610e4c90614523565b80601f0160208091040260200160405190810160405280929190818152602001828054610e7890614523565b8015610deb5780601f10610e9a57610100808354040283529160200191610deb565b820191906000526020600020905b815481529060010190602001808311610ea857509395945050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610f37576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600082815260076020526040902054610f5257506000919050565b60008281526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f41690610f959084815260200190565b60405180910390a15060015b919050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611015576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61067e81612a2c565b600854600c54604080517ffeaf968c0000000000000000000000000000000000000000000000000000000081529051600093640100000000900463ffffffff169283151592859283926c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff169163feaf968c9160048083019260a09291908290030181865afa1580156110b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110dc91906148dc565b509350509250508280156110fe57506110f5814261492c565b8463ffffffff16105b1561110957600a5491505b509392505050565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff808216602085015261010090910416928201929092529083146111f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610bfa565b6112068b8b8b8b8b8b612d35565b60007f00000000000000000000000000000000000000000000000000000000000000001561126357600282602001518360400151611244919061493f565b61124e9190614987565b61125990600161493f565b60ff169050611279565b602082015161127390600161493f565b60ff1690505b8881146112e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610bfa565b88871461134b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610bfa565b3360009081526004602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561138e5761138e6149a9565b600281111561139f5761139f6149a9565b90525090506002816020015160028111156113bc576113bc6149a9565b14801561140357506006816000015160ff16815481106113de576113de614800565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611469576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610bfa565b5050505050611476613b01565b6000808a8a6040516114899291906149d8565b6040519081900381206114a0918e906020016149e8565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156117aa57600060018489846020811061150957611509614800565b61151691901a601b61493f565b8e8e8681811061152857611528614800565b905060200201358d8d8781811061154157611541614800565b905060200201356040516000815260200160405260405161157e949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156115a0573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff80821685529296509294508401916101009004166002811115611620576116206149a9565b6002811115611631576116316149a9565b905250925060018360200151600281111561164e5761164e6149a9565b146116b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610bfa565b8251600090879060ff16601f81106116cf576116cf614800565b602002015173ffffffffffffffffffffffffffffffffffffffff1614611751576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610bfa565b8086846000015160ff16601f811061176b5761176b614800565b73ffffffffffffffffffffffffffffffffffffffff909216602092909202015261179660018661493f565b945050806117a39061485e565b90506114ea565b5050506117bb833383858e8e612de3565b5050505050505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611890576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61189d60408301836149fc565b90506000036118d7576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518060a001604052808460600160208101906118f79190614a61565b67ffffffffffffffff16815260209081019061191590860186613edb565b73ffffffffffffffffffffffffffffffffffffffff16815260200161194060e0860160c08701614a7e565b63ffffffff1681523a6020820152604001611962610100860160e08701614a9b565b6bffffffffffffffffffffffff16905290506119cf61198460408501856149fc565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506119c99250505060a0860160808701614ab8565b83612fb1565b91506119de6020840184613edb565b73ffffffffffffffffffffffffffffffffffffffff168260e001517fd88ef982f3624222a23ef83ed2192cbdfba8e1e474a6cb1d315736d08479d2e332866060016020810190611a2e9190614a61565b611a3e6040890160208a01613edb565b611a4b60408a018a6149fc565b611a5b60a08c0160808d01614ab8565b60a08c0135611a7060e08e0160c08f01614a7e565b8c604051602001611a81919061432e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611ac1999897969594939291614ad5565b60405180910390a350919050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b158015611b6f57600080fd5b505afa158015611b83573d6000803e3d6000fd5b50505050620f4240821115611bc4576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611bce610681565b905060006040518060a001604052808967ffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018663ffffffff168152602001858152602001836bffffffffffffffffffffffff1681525090506000611c7288888080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508692506105ad915050565b69ffffffffffffffffffff169050611c8c868683866134a7565b93505050505b95945050505050565b6060600d8054611caa90614523565b9050600003611ce5576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610e4c90614523565b855185518560ff16601f831115611d65576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610bfa565b80600003611dcf576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610bfa565b818314611e5d576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610bfa565b611e68816003614b99565b8311611ed0576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610bfa565b611ed861272f565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611f1f9088613617565b600554156120d457600554600090611f399060019061492c565b9050600060058281548110611f5057611f50614800565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611f8a57611f8a614800565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009081169091559290911680845292208054909116905560058054919250908061200a5761200a614bb0565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055600680548061207357612073614bb0565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611f1f915050565b60005b81515181101561253b57600060046000846000015184815181106120fd576120fd614800565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff166002811115612147576121476149a9565b146121ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610bfa565b6040805180820190915260ff821681526001602082015282518051600491600091859081106121df576121df614800565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115612280576122806149a9565b0217905550600091506122909050565b60046000846020015184815181106122aa576122aa614800565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff1660028111156122f4576122f46149a9565b1461235b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610bfa565b6040805180820190915260ff82168152602081016002815250600460008460200151848151811061238e5761238e614800565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561242f5761242f6149a9565b02179055505082518051600592508390811061244d5761244d614800565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160069190839081106124c9576124c9614800565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055806125338161485e565b9150506120d7565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff43811682029290921780855592048116929182916014916125f391849174010000000000000000000000000000000000000000900416614bdf565b92506101000a81548163ffffffff021916908363ffffffff1602179055506126524630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a00151613634565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0598612709988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192614bfc565b60405180910390a15050505050505050505050565b61272661272f565b61067e816136df565b60005473ffffffffffffffffffffffffffffffffffffffff1633146127b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610bfa565b565b60006127bc610d86565b905080516000036127f9576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600c54600091612818916bffffffffffffffffffffffff16614c92565b905060005b82518110156128e45781600b600085848151811061283d5761283d614800565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff166128a59190614cbd565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550806128dd9061485e565b905061281d565b5081516128f19082614ce2565b600c80546000906129119084906bffffffffffffffffffffffff16614896565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b60008060068054806020026020016040519081016040528092919081815260200182805480156129a957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161297e575b5050505050905060005b8151811015612a22578373ffffffffffffffffffffffffffffffffffffffff168282815181106129e5576129e5614800565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603612a12575060019392505050565b612a1b8161485e565b90506129b3565b5060009392505050565b600080600080600080600080600089806020019051810190612a4e9190614d12565b98509850985098509850985098509850985060008113612a9d576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101829052602401610bfa565b604080516101208101825263ffffffff808c168083528b8216602084018190528b83168486018190528b841660608601819052938b166080860181905269ffffffffffffffffffff8b1660a0870181905261ffff8b1660c0880181905260e088018b9052610100909701899052600880547e010000000000000000000000000000000000000000000000000000000000009098027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff740100000000000000000000000000000000000000009093027fffff00000000000000000000ffffffffffffffffffffffffffffffffffffffff700100000000000000000000000000000000909502949094167fffff0000000000000000000000000000ffffffffffffffffffffffffffffffff6c010000000000000000000000009099027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff68010000000000000000909702969096167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff6401000000009098027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b1690981799909917959095169590951792909217949094169490941792909217929092161790556009839055600a829055517f3332571032ee658b30d567e63b2443e9d921162625e0f3fe86968a586c1a090f90612d21908b908b908b908b908b908b908b908b908b9063ffffffff998a16815297891660208901529588166040880152938716606087015291909516608085015269ffffffffffffffffffff9490941660a084015261ffff9390931660c083015260e08201929092526101008101919091526101200190565b60405180910390a150505050505050505050565b6000612d42826020614b99565b612d4d856020614b99565b612d5988610144614dbe565b612d639190614dbe565b612d6d9190614dbe565b612d78906000614dbe565b9050368114610b74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610bfa565b606080808080612df586880188614eac565b8451949950929750909550935091501580612e1257508351855114155b80612e1f57508251855114155b80612e2c57508151855114155b80612e3957508051855114155b15612e70576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8551811015612fa3576000612f08878381518110612e9357612e93614800565b6020026020010151878481518110612ead57612ead614800565b6020026020010151878581518110612ec757612ec7614800565b6020026020010151878681518110612ee157612ee1614800565b6020026020010151878781518110612efb57612efb614800565b60200260200101516137d4565b90506000816006811115612f1e57612f1e6149a9565b1480612f3b57506001816006811115612f3957612f396149a9565b145b15612f9257868281518110612f5257612f52614800565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b50612f9c8161485e565b9050612e73565b505050505050505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081018290526101008101829052610120810182905261014081019190915260085461ffff7e0100000000000000000000000000000000000000000000000000000000000090910481169084161115613070576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061307c85846105ad565b905060006130a4846040015185606001518469ffffffffffffffffffff1687608001516134a7565b905060007f000000000000000000000000000000000000000000000000000000000000000085516040517fa47c769600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff9091166004820152909150600090819073ffffffffffffffffffffffffffffffffffffffff84169063a47c769690602401600060405180830381865afa158015613148573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261318e9190810190614f89565b50505060208a01518a516040517f674603d000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff9091166024820152939550909350600092908616915063674603d090604401606060405180830381865afa158015613220573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132449190615088565b509150506bffffffffffffffffffffffff85166132618385614896565b6bffffffffffffffffffffffff1610156132a7576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000613326308a602001518b600001518560016132c491906150da565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b90506040518061016001604052808a608001516bffffffffffffffffffffffff1681526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015173ffffffffffffffffffffffffffffffffffffffff1681526020018a6000015167ffffffffffffffff1681526020018a6040015163ffffffff168152602001876bffffffffffffffffffffffff168152602001600860000160109054906101000a900463ffffffff1663ffffffff16426133e79190614dbe565b64ffffffffff168152602080820184905269ffffffffffffffffffff8a1660408084019190915260085463ffffffff680100000000000000008204811660608601526c01000000000000000000000000909104166080909301929092529051919950613455918a910161432e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000938452600790925290912055509498975050505050505050565b6000806134b261101e565b9050600081136134f1576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101829052602401610bfa565b60085460009087906135279063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614bdf565b6135319190614bdf565b63ffffffff16905060006127106008600101548861354f9190614b99565b61355991906150fb565b6135639088614dbe565b90506000838361357b84670de0b6b3a7640000614b99565b6135859190614b99565b61358f91906150fb565b905060006135ae6bffffffffffffffffffffffff808916908a16614dbe565b90506135c6816b033b2e3c9fd0803ce800000061492c565b8211156135ff576040517fe80fa38100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6136098183614dbe565b9a9950505050505050505050565b6000613621610d86565b511115613630576136306127b2565b5050565b6000808a8a8a8a8a8a8a8a8a6040516020016136589998979695949392919061510f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361375e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610bfa565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080838060200190518101906137eb91906151b9565b60008881526007602052604090205490915061380b576002915050611c92565b8060405160200161381c919061432e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008a815260079093529120541461386e576006915050611c92565b600061387861101e565b9050600081136138b7576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101829052602401610bfa565b6000816138cc3a670de0b6b3a7640000614b99565b6138d691906150fb565b905060008361014001518461012001516138f0919061528c565b6139019064ffffffffff1683614b99565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a1d4c8288c8c878a610100015169ffffffffffffffffffff16886139629190614cbd565b338c6040518763ffffffff1660e01b8152600401613985969594939291906152aa565b60408051808303816000875af11580156139a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139c79190615326565b909250905060008260068111156139e0576139e06149a9565b14806139fd575060018260068111156139fb576139fb6149a9565b145b15613ab85760008c815260076020526040812055613a1b8184614cbd565b336000908152600b6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff938416179055610100880151600c805469ffffffffffffffffffff90921693909291613a8991859116614cbd565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b509a9950505050505050505050565b508054613ad390614523565b6000825580601f10613ae3575050565b601f01602090049060005260206000209081019061067e9190613b20565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613b355760008155600101613b21565b5090565b60008083601f840112613b4b57600080fd5b50813567ffffffffffffffff811115613b6357600080fd5b602083019150836020828501011115613b7b57600080fd5b9250929050565b60008060208385031215613b9557600080fd5b823567ffffffffffffffff811115613bac57600080fd5b613bb885828601613b39565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613c1657613c16613bc4565b60405290565b604051610160810167ffffffffffffffff81118282101715613c1657613c16613bc4565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613c8757613c87613bc4565b604052919050565b600082601f830112613ca057600080fd5b813567ffffffffffffffff811115613cba57613cba613bc4565b613ceb60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613c40565b818152846020838601011115613d0057600080fd5b816020850160208301376000918101602001919091529392505050565b67ffffffffffffffff8116811461067e57600080fd5b8035610fa181613d1d565b73ffffffffffffffffffffffffffffffffffffffff8116811461067e57600080fd5b63ffffffff8116811461067e57600080fd5b6bffffffffffffffffffffffff8116811461067e57600080fd5b60008082840360c0811215613da057600080fd5b833567ffffffffffffffff811115613db757600080fd5b613dc386828701613c8f565b93505060a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082011215613df657600080fd5b50613dff613bf3565b6020840135613e0d81613d1d565b81526040840135613e1d81613d3e565b60208201526060840135613e3081613d60565b60408201526080840135606082015260a0840135613e4d81613d72565b6080820152919491935090915050565b6000815180845260005b81811015613e8357602081850181015186830182015201613e67565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000613ed46020830184613e5d565b9392505050565b600060208284031215613eed57600080fd5b8135613ed481613d3e565b600081518084526020808501945080840160005b83811015613f3e57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613f0c565b509495945050505050565b604081526000613f5c6040830185613ef8565b6020838203818501528185518084528284019150828160051b85010183880160005b83811015613fca577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0878403018552613fb8838351613e5d565b94860194925090850190600101613f7e565b50909998505050505050505050565b60008060408385031215613fec57600080fd5b8235613ff781613d3e565b9150602083013561400781613d72565b809150509250929050565b60008060006040848603121561402757600080fd5b833561403281613d3e565b9250602084013567ffffffffffffffff81111561404e57600080fd5b61405a86828701613b39565b9497909650939450505050565b602081526000613ed46020830184613ef8565b60006020828403121561408c57600080fd5b5035919050565b6000602082840312156140a557600080fd5b813567ffffffffffffffff8111156140bc57600080fd5b6140c884828501613c8f565b949350505050565b60008083601f8401126140e257600080fd5b50813567ffffffffffffffff8111156140fa57600080fd5b6020830191508360208260051b8501011115613b7b57600080fd5b60008060008060008060008060e0898b03121561413157600080fd5b606089018a81111561414257600080fd5b8998503567ffffffffffffffff8082111561415c57600080fd5b6141688c838d01613b39565b909950975060808b013591508082111561418157600080fd5b61418d8c838d016140d0565b909750955060a08b01359150808211156141a657600080fd5b506141b38b828c016140d0565b999c989b50969995989497949560c00135949350505050565b6000602082840312156141de57600080fd5b813567ffffffffffffffff8111156141f557600080fd5b82016101008185031215613ed457600080fd5b80516bffffffffffffffffffffffff1682526020810151614241602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040810151614269604084018273ffffffffffffffffffffffffffffffffffffffff169052565b506060810151614285606084018267ffffffffffffffff169052565b50608081015161429d608084018263ffffffff169052565b5060a08101516142bd60a08401826bffffffffffffffffffffffff169052565b5060c08101516142d660c084018264ffffffffff169052565b5060e081015160e0830152610100808201516142ff8285018269ffffffffffffffffffff169052565b50506101208181015164ffffffffff81168483015250506101408181015164ffffffffff811684830152610d80565b61016081016105d58284614208565b60008060008060006080868803121561435557600080fd5b853561436081613d1d565b9450602086013567ffffffffffffffff81111561437c57600080fd5b61438888828901613b39565b909550935050604086013561439c81613d60565b949793965091946060013592915050565b600067ffffffffffffffff8211156143c7576143c7613bc4565b5060051b60200190565b600082601f8301126143e257600080fd5b813560206143f76143f2836143ad565b613c40565b82815260059290921b8401810191818101908684111561441657600080fd5b8286015b8481101561443a57803561442d81613d3e565b835291830191830161441a565b509695505050505050565b803560ff81168114610fa157600080fd5b60008060008060008060c0878903121561446f57600080fd5b863567ffffffffffffffff8082111561448757600080fd5b6144938a838b016143d1565b975060208901359150808211156144a957600080fd5b6144b58a838b016143d1565b96506144c360408a01614445565b955060608901359150808211156144d957600080fd5b6144e58a838b01613c8f565b94506144f360808a01613d33565b935060a089013591508082111561450957600080fd5b5061451689828a01613c8f565b9150509295509295509295565b600181811c9082168061453757607f821691505b602082108103614570577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105a857600081815260208120601f850160051c8101602086101561459d5750805b601f850160051c820191505b818110156145bc578281556001016145a9565b505050505050565b67ffffffffffffffff8311156145dc576145dc613bc4565b6145f0836145ea8354614523565b83614576565b6000601f841160018114614642576000851561460c5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b1783556146d8565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156146915786850135825560209485019460019092019101614671565b50868210156146cc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff8116811461067e57600080fd5b8051610fa181613d72565b8051610fa181613d60565b6000806000806080858703121561471b57600080fd5b8451614726816146df565b8094505060208086015161473981613d72565b60408701519094507fffffffff000000000000000000000000000000000000000000000000000000008116811461476f57600080fd5b606087015190935067ffffffffffffffff81111561478c57600080fd5b8601601f8101881361479d57600080fd5b80516147ab6143f2826143ad565b81815260059190911b8201830190838101908a8311156147ca57600080fd5b928401925b828410156147f15783516147e281613d60565b825292840192908401906147cf565b979a9699509497505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361488f5761488f61482f565b5060010190565b6bffffffffffffffffffffffff8281168282160390808211156148bb576148bb61482f565b5092915050565b805169ffffffffffffffffffff81168114610fa157600080fd5b600080600080600060a086880312156148f457600080fd5b6148fd866148c2565b9450602086015193506040860151925060608601519150614920608087016148c2565b90509295509295909350565b818103818111156105d5576105d561482f565b60ff81811683821601908111156105d5576105d561482f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff83168061499a5761499a614958565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614a3157600080fd5b83018035915067ffffffffffffffff821115614a4c57600080fd5b602001915036819003821315613b7b57600080fd5b600060208284031215614a7357600080fd5b8135613ed481613d1d565b600060208284031215614a9057600080fd5b8135613ed481613d60565b600060208284031215614aad57600080fd5b8135613ed481613d72565b600060208284031215614aca57600080fd5b8135613ed4816146df565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a16602083015288166040820152610100606082018190528101869052600061012087898285013760008189850101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f890116830161ffff881660808501528660a0850152614b7260c085018763ffffffff169052565b818482030160e0850152614b8882820186613e5d565b9d9c50505050505050505050505050565b80820281158282048414176105d5576105d561482f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff8181168382160190808211156148bb576148bb61482f565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614c2c8184018a613ef8565b90508281036080840152614c408189613ef8565b905060ff871660a084015282810360c0840152614c5d8187613e5d565b905067ffffffffffffffff851660e0840152828103610100840152614c828185613e5d565b9c9b505050505050505050505050565b60006bffffffffffffffffffffffff80841680614cb157614cb1614958565b92169190910492915050565b6bffffffffffffffffffffffff8181168382160190808211156148bb576148bb61482f565b6bffffffffffffffffffffffff818116838216028082169190828114614d0a57614d0a61482f565b505092915050565b60008060008060008060008060006101208a8c031215614d3157600080fd5b8951614d3c81613d60565b60208b0151909950614d4d81613d60565b60408b0151909850614d5e81613d60565b60608b0151909750614d6f81613d60565b60808b0151909650614d8081613d60565b9450614d8e60a08b016148c2565b935060c08a0151614d9e816146df565b8093505060e08a015191506101008a015190509295985092959850929598565b808201808211156105d5576105d561482f565b600082601f830112614de257600080fd5b81356020614df26143f2836143ad565b82815260059290921b84018101918181019086841115614e1157600080fd5b8286015b8481101561443a5780358352918301918301614e15565b600082601f830112614e3d57600080fd5b81356020614e4d6143f2836143ad565b82815260059290921b84018101918181019086841115614e6c57600080fd5b8286015b8481101561443a57803567ffffffffffffffff811115614e905760008081fd5b614e9e8986838b0101613c8f565b845250918301918301614e70565b600080600080600060a08688031215614ec457600080fd5b853567ffffffffffffffff80821115614edc57600080fd5b614ee889838a01614dd1565b96506020880135915080821115614efe57600080fd5b614f0a89838a01614e2c565b95506040880135915080821115614f2057600080fd5b614f2c89838a01614e2c565b94506060880135915080821115614f4257600080fd5b614f4e89838a01614e2c565b93506080880135915080821115614f6457600080fd5b50614f7188828901614e2c565b9150509295509295909350565b8051610fa181613d3e565b60008060008060008060c08789031215614fa257600080fd5b8651614fad81613d72565b80965050602080880151614fc081613d3e565b6040890151909650614fd181613d72565b6060890151909550614fe281613d3e565b608089015190945067ffffffffffffffff811115614fff57600080fd5b8801601f81018a1361501057600080fd5b805161501e6143f2826143ad565b81815260059190911b8201830190838101908c83111561503d57600080fd5b928401925b8284101561506457835161505581613d3e565b82529284019290840190615042565b809650505050505060a087015190509295509295509295565b8051610fa181613d1d565b60008060006060848603121561509d57600080fd5b835180151581146150ad57600080fd5b60208501519093506150be81613d1d565b60408501519092506150cf81613d1d565b809150509250925092565b67ffffffffffffffff8181168382160190808211156148bb576148bb61482f565b60008261510a5761510a614958565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526151568285018b613ef8565b9150838203608085015261516a828a613ef8565b915060ff881660a085015283820360c08501526151878288613e5d565b90861660e08501528381036101008501529050614c828185613e5d565b805164ffffffffff81168114610fa157600080fd5b600061016082840312156151cc57600080fd5b6151d4613c1c565b6151dd836146ef565b81526151eb60208401614f7e565b60208201526151fc60408401614f7e565b604082015261520d6060840161507d565b606082015261521e608084016146fa565b608082015261522f60a084016146ef565b60a082015261524060c084016151a4565b60c082015260e083015160e082015261010061525d8185016148c2565b9082015261012061526f8482016151a4565b908201526101406152818482016151a4565b908201529392505050565b64ffffffffff8181168382160190808211156148bb576148bb61482f565b60006102008083526152be8184018a613e5d565b905082810360208401526152d28189613e5d565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff86166080850152915061531b905060a0830184614208565b979650505050505050565b6000806040838503121561533957600080fd5b82516007811061534857600080fd5b602084015190925061400781613d7256fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"linkToNativeFeed\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"EmptyPublicKey\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyRequestData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InconsistentReportData\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoTransmittersSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRouterOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ReportInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustBeSet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedPublicKeyChange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSender\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedRequestDataVersion\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"CommitmentDeleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint80\",\"name\":\"donFee\",\"type\":\"uint80\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"int256\"}],\"indexed\":false,\"internalType\":\"structIFunctionsBilling.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"previousConfigBlockNumber\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"configCount\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"signers\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"transmitters\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"f\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"onchainConfig\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"offchainConfigVersion\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"offchainConfig\",\"type\":\"bytes\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"callbackGasLimit\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"commitment\",\"type\":\"bytes\"}],\"name\":\"OracleRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"}],\"name\":\"OracleResponse\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"name\":\"Transmitted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"deleteCommitment\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"}],\"name\":\"deleteNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"gasPriceGwei\",\"type\":\"uint256\"}],\"name\":\"estimateCost\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAdminFee\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllNodePublicKeys\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxCallbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"feedStalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"requestTimeoutSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint80\",\"name\":\"donFee\",\"type\":\"uint80\"},{\"internalType\":\"uint16\",\"name\":\"maxSupportedRequestDataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint256\",\"name\":\"fulfillmentGasPriceOverEstimationBP\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"fallbackNativePerUnitLink\",\"type\":\"int256\"}],\"internalType\":\"structIFunctionsBilling.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"expectedGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"}],\"internalType\":\"structIFunctionsBilling.RequestBilling\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"getDONFee\",\"outputs\":[{\"internalType\":\"uint80\",\"name\":\"\",\"type\":\"uint80\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDONPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getThresholdPublicKey\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"oracleWithdrawAll\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"}],\"internalType\":\"structIFunctionsCoordinator.Request\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"sendRequest\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"uint40\",\"name\":\"timeoutTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint80\",\"name\":\"donFee\",\"type\":\"uint80\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"_signers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"_transmitters\",\"type\":\"address[]\"},{\"internalType\":\"uint8\",\"name\":\"_f\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"_onchainConfig\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"_offchainConfigVersion\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"_offchainConfig\",\"type\":\"bytes\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"donPublicKey\",\"type\":\"bytes\"}],\"name\":\"setDONPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"node\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"publicKey\",\"type\":\"bytes\"}],\"name\":\"setNodePublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"thresholdPublicKey\",\"type\":\"bytes\"}],\"name\":\"setThresholdPublicKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"transmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b5060405162005cd638038062005cd6833981016040819052620000349162000405565b828282828260013380600081620000925760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c557620000c5816200014a565b50505015156080526001600160a01b038216620000f557604051632530e88560e11b815260040160405180910390fd5b6001600160a01b03821660a0526200010d81620001f5565b5050600c80546001600160a01b039092166c01000000000000000000000000026001600160601b0390921691909117905550620006709350505050565b336001600160a01b03821603620001a45760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000089565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818060200190518101906200020d919062000522565b905060008161010001511362000240578061010001516040516321ea67b360e11b81526004016200008991815260200190565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff16600160f01b026001600160f01b036001600160501b03909216600160a01b02600160a01b600160f01b031963ffffffff948516600160801b0216600160801b600160f01b03199585166c010000000000000000000000000263ffffffff60601b19978616680100000000000000000297909716600160401b600160801b0319998616640100000000026001600160401b0319909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600955610100820151600a55517ffc10ed3768699b4370d710cd8ffbc7efdc5a691e42af93f2fe3d0ba7c33556589062000367908390620005dd565b60405180910390a15050565b80516001600160a01b03811681146200038b57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60405161012081016001600160401b0381118282101715620003cc57620003cc62000390565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620003fd57620003fd62000390565b604052919050565b6000806000606084860312156200041b57600080fd5b620004268462000373565b602085810151919450906001600160401b03808211156200044657600080fd5b818701915087601f8301126200045b57600080fd5b81518181111562000470576200047062000390565b62000484601f8201601f19168501620003d2565b915080825288848285010111156200049b57600080fd5b60005b81811015620004bb5783810185015183820186015284016200049e565b50600084828401015250809450505050620004d96040850162000373565b90509250925092565b805163ffffffff811681146200038b57600080fd5b80516001600160501b03811681146200038b57600080fd5b805161ffff811681146200038b57600080fd5b600061012082840312156200053657600080fd5b62000540620003a6565b6200054b83620004e2565b81526200055b60208401620004e2565b60208201526200056e60408401620004e2565b60408201526200058160608401620004e2565b60608201526200059460808401620004e2565b6080820152620005a760a08401620004f7565b60a0820152620005ba60c084016200050f565b60c082015260e08381015190820152610100928301519281019290925250919050565b815163ffffffff9081168252602080840151821690830152604080840151821690830152606080840151821690830152608080840151918216908301526101208201905060a08301516200063c60a08401826001600160501b03169052565b5060c08301516200065360c084018261ffff169052565b5060e083015160e083015261010080840151818401525092915050565b60805160a051615608620006ce600039600081816106cc01528181610aa701528181610cd50152818161101f015281816110fd0152818161188501528181611b1f015281816132f40152613a2a0152600061125601526156086000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806381ff7048116100ee578063bdd7e88011610097578063d328a91e11610071578063d328a91e1461055b578063e3d0e71214610563578063e4ddcea614610576578063f2fde38b1461058c57600080fd5b8063bdd7e880146103f6578063c3f909d414610416578063d227d2451461054857600080fd5b80638da5cb5b116100c85780638da5cb5b1461039b578063afcb95d7146103c3578063b1dc65a4146103e357600080fd5b806381ff7048146102f857806385b214cf146103655780638cc6acce1461038857600080fd5b806366316d8d1161015b5780637f15e166116101355780637f15e166146102b557806380756031146102c857806381411834146102db57806381f1b938146102f057600080fd5b806366316d8d1461029257806379ba5097146102a55780637d480787146102ad57600080fd5b806326ceabac1161018c57806326ceabac146102445780632a905ccc14610257578063533989871461027c57600080fd5b8063083a5466146101b35780630e7ada39146101c8578063181f5a77146101fb575b600080fd5b6101c66101c1366004613cc9565b61059f565b005b6101db6101d6366004613f3d565b6105f4565b60405169ffffffffffffffffffff90911681526020015b60405180910390f35b6102376040518060400160405280601c81526020017f46756e6374696f6e7320436f6f7264696e61746f722076312e302e300000000081525081565b6040516101f29190614072565b6101c661025236600461408c565b610622565b61025f6106c8565b6040516bffffffffffffffffffffffff90911681526020016101f2565b610284610784565b6040516101f29291906140fa565b6101c66102a036600461418a565b6109ab565b6101c6610b64565b6101c6610c66565b6101c66102c3366004613cc9565b610dbe565b6101c66102d63660046141c3565b610e0e565b6102e3610ec5565b6040516101f29190614218565b610237610f34565b61034260015460025463ffffffff74010000000000000000000000000000000000000000830481169378010000000000000000000000000000000000000000000000009093041691565b6040805163ffffffff9485168152939092166020840152908201526060016101f2565b61037861037336600461422b565b611005565b60405190151581526020016101f2565b6101c6610396366004614244565b6110e5565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f2565b6040805160018152600060208201819052918101919091526060016101f2565b6101c66103f13660046142c6565b61115d565b61040961040436600461437d565b611814565b6040516101f291906144df565b61053b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081019190915250604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015274010000000000000000000000000000000000000000820469ffffffffffffffffffff1660a08201527e0100000000000000000000000000000000000000000000000000000000000090910461ffff1660c082015260095460e0820152600a5461010082015290565b6040516101f291906144ee565b61025f610556366004614582565b611b1b565b610237611ccd565b6101c661057136600461469b565b611d24565b61057e612750565b6040519081526020016101f2565b6101c661059a36600461408c565b612945565b6105a7612956565b60008190036105e2576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f6105ef828483614801565b505050565b60085474010000000000000000000000000000000000000000900469ffffffffffffffffffff165b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061066057503373ffffffffffffffffffffffffffffffffffffffff821614155b15610697576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600e602052604081206106c591613c0e565b50565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c3f909d46040518163ffffffff1660e01b8152600401600060405180830381865afa158015610735573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261077b919081019061494d565b60200151905090565b606080600060068054806020026020016040519081016040528092919081815260200182805480156107ec57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116107c1575b505050505090506000815167ffffffffffffffff81111561080f5761080f613d0b565b60405190808252806020026020018201604052801561084257816020015b606081526020019060019003908161082d5790505b50905060005b82518110156109a1576000600e600085848151811061086957610869614a77565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546108b690614768565b80601f01602080910402602001604051908101604052809291908181526020018280546108e290614768565b801561092f5780601f106109045761010080835404028352916020019161092f565b820191906000526020600020905b81548152906001019060200180831161091257829003601f168201915b505050505090508051600003610971576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8083838151811061098457610984614a77565b6020026020010181905250508061099a90614ad5565b9050610848565b5090939092509050565b6109b36129d9565b806bffffffffffffffffffffffff166000036109ed5750336000908152600b60205260409020546bffffffffffffffffffffffff16610a47565b336000908152600b60205260409020546bffffffffffffffffffffffff80831691161015610a47576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600b602052604081208054839290610a749084906bffffffffffffffffffffffff16614b0d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550610ac97f000000000000000000000000000000000000000000000000000000000000000090565b6040517f66316d8d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301526bffffffffffffffffffffffff8416602483015291909116906366316d8d90604401600060405180830381600087803b158015610b4857600080fd5b505af1158015610b5c573d6000803e3d6000fd5b505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610bea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610c6e612b84565b610c766129d9565b6000610c80610ec5565b905060005b8151811015610dba57336000908152600b6020526040902080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000081169091556bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166366316d8d848481518110610d2157610d21614a77565b6020026020010151836040518363ffffffff1660e01b8152600401610d7692919073ffffffffffffffffffffffffffffffffffffffff9290921682526bffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610d9057600080fd5b505af1158015610da4573d6000803e3d6000fd5b505050505080610db390614ad5565b9050610c85565b5050565b610dc6612956565b6000819003610e01576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d6105ef828483614801565b60005473ffffffffffffffffffffffffffffffffffffffff16331480610e595750610e3833612b8c565b8015610e5957503373ffffffffffffffffffffffffffffffffffffffff8416145b610e8f576040517fed6dd19b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff83166000908152600e60205260409020610ebf828483614801565b50505050565b60606006805480602002602001604051908101604052809291908181526020018280548015610f2a57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610eff575b5050505050905090565b6060600f8054610f4390614768565b9050600003610f7e576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f8054610f8b90614768565b80601f0160208091040260200160405190810160405280929190818152602001828054610fb790614768565b8015610f2a5780601f10610fd957610100808354040283529160200191610f2a565b820191906000526020600020905b815481529060010190602001808311610fe757509395945050505050565b60003373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611076576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008281526007602052604090205461109157506000919050565b60008281526007602052604080822091909155517f8a4b97add3359bd6bcf5e82874363670eb5ad0f7615abddbd0ed0a3a98f0f416906110d49084815260200190565b60405180910390a15060015b919050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614611154576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106c581612c75565b60005a604080518b3580825262ffffff6020808f0135600881901c929092169084015293945092917fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a16040805160608101825260025480825260035460ff80821660208501526101009091041692820192909252908314611244576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f636f6e666967446967657374206d69736d6174636800000000000000000000006044820152606401610be1565b6112528b8b8b8b8b8b612ec8565b60007f0000000000000000000000000000000000000000000000000000000000000000156112af576002826020015183604001516112909190614b32565b61129a9190614b7a565b6112a5906001614b32565b60ff1690506112c5565b60208201516112bf906001614b32565b60ff1690505b88811461132e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f77726f6e67206e756d626572206f66207369676e6174757265730000000000006044820152606401610be1565b888714611397576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f7369676e617475726573206f7574206f6620726567697374726174696f6e00006044820152606401610be1565b3360009081526004602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156113da576113da614b9c565b60028111156113eb576113eb614b9c565b905250905060028160200151600281111561140857611408614b9c565b14801561144f57506006816000015160ff168154811061142a5761142a614a77565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6114b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f756e617574686f72697a6564207472616e736d697474657200000000000000006044820152606401610be1565b50505050506114c2613c48565b6000808a8a6040516114d5929190614bcb565b6040519081900381206114ec918e90602001614bdb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120838301909252600080845290830152915060005b898110156117f657600060018489846020811061155557611555614a77565b61156291901a601b614b32565b8e8e8681811061157457611574614a77565b905060200201358d8d8781811061158d5761158d614a77565b90506020020135604051600081526020016040526040516115ca949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa1580156115ec573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff811660009081526004602090815290849020838501909452835460ff8082168552929650929450840191610100900416600281111561166c5761166c614b9c565b600281111561167d5761167d614b9c565b905250925060018360200151600281111561169a5761169a614b9c565b14611701576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f61646472657373206e6f7420617574686f72697a656420746f207369676e00006044820152606401610be1565b8251600090879060ff16601f811061171b5761171b614a77565b602002015173ffffffffffffffffffffffffffffffffffffffff161461179d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f6e6f6e2d756e69717565207369676e61747572650000000000000000000000006044820152606401610be1565b8086846000015160ff16601f81106117b7576117b7614a77565b73ffffffffffffffffffffffffffffffffffffffff90921660209290920201526117e2600186614b32565b945050806117ef90614ad5565b9050611536565b505050611807833383858e8e612f7f565b5050505050505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091523373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146118dc576040517fc41a5b0900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118e96040830183614bef565b9050600003611923576040517ec1cfc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006040518060a001604052808460600160208101906119439190614c54565b67ffffffffffffffff1681526020908101906119619086018661408c565b73ffffffffffffffffffffffffffffffffffffffff16815260200161198c60e0860160c08701614c71565b63ffffffff1681523a60208201526040016119ae610100860160e08701614c8e565b6bffffffffffffffffffffffff1690529050611a1b6119d06040850185614bef565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611a159250505060a0860160808701614cab565b8361314d565b9150611a2a602084018461408c565b73ffffffffffffffffffffffffffffffffffffffff168260e001517fd88ef982f3624222a23ef83ed2192cbdfba8e1e474a6cb1d315736d08479d2e332866060016020810190611a7a9190614c54565b611a8a6040890160208a0161408c565b611a9760408a018a614bef565b611aa760a08c0160808d01614cab565b60a08c0135611abc60e08e0160c08f01614c71565b8c604051602001611acd91906144df565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052611b0d999897969594939291614cc8565b60405180910390a350919050565b60007f00000000000000000000000000000000000000000000000000000000000000006040517f10fc49c100000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8816600482015263ffffffff8516602482015273ffffffffffffffffffffffffffffffffffffffff91909116906310fc49c19060440160006040518083038186803b158015611bbb57600080fd5b505afa158015611bcf573d6000803e3d6000fd5b505050620f42408311159050611c11576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611c1b6106c8565b90506000611ca587878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250506040805160a08101825267ffffffffffffffff8e16815233602082015263ffffffff8b1691810191909152606081018990526bffffffffffffffffffffffff8716608082015291506105f49050565b69ffffffffffffffffffff169050611cbf858583856136d3565b925050505b95945050505050565b6060600d8054611cdc90614768565b9050600003611d17576040517f4f42be3d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600d8054610f8b90614768565b855185518560ff16601f831115611d97576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e657273000000000000000000000000000000006044820152606401610be1565b80600003611e01576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610be1565b818314611e8f576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610be1565b611e9a816003614d8c565b8311611f02576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610be1565b611f0a612956565b6040805160c0810182528a8152602081018a905260ff89169181018290526060810188905267ffffffffffffffff8716608082015260a0810186905290611f51908861379b565b6005541561210657600554600090611f6b90600190614da3565b9050600060058281548110611f8257611f82614a77565b60009182526020822001546006805473ffffffffffffffffffffffffffffffffffffffff90921693509084908110611fbc57611fbc614a77565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff85811684526004909252604080842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00009081169091559290911680845292208054909116905560058054919250908061203c5761203c614db6565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905560068054806120a5576120a5614db6565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611f51915050565b60005b81515181101561256d576000600460008460000151848151811061212f5761212f614a77565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561217957612179614b9c565b146121e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610be1565b6040805180820190915260ff8216815260016020820152825180516004916000918590811061221157612211614a77565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016176101008360028111156122b2576122b2614b9c565b0217905550600091506122c29050565b60046000846020015184815181106122dc576122dc614a77565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002054610100900460ff16600281111561232657612326614b9c565b1461238d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610be1565b6040805180820190915260ff8216815260208101600281525060046000846020015184815181106123c0576123c0614a77565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040016000208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000161761010083600281111561246157612461614b9c565b02179055505082518051600592508390811061247f5761247f614a77565b602090810291909101810151825460018101845560009384529282902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90931692909217909155820151805160069190839081106124fb576124fb614a77565b60209081029190910181015182546001810184556000938452919092200180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790558061256581614ad5565b915050612109565b506040810151600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff909216919091179055600180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff8116780100000000000000000000000000000000000000000000000063ffffffff438116820292909217808555920481169291829160149161262591849174010000000000000000000000000000000000000000900416614de5565b92506101000a81548163ffffffff021916908363ffffffff1602179055506126844630600160149054906101000a900463ffffffff1663ffffffff16856000015186602001518760400151886060015189608001518a60a001516137b4565b600281905582518051600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1661010060ff9093169290920291909117905560015460208501516040808701516060880151608089015160a08a015193517f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e059861273b988b9891977401000000000000000000000000000000000000000090920463ffffffff16969095919491939192614e02565b60405180910390a15050505050505050505050565b604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116838501526c01000000000000000000000000808304821660608501527001000000000000000000000000000000008304909116608084015274010000000000000000000000000000000000000000820469ffffffffffffffffffff1660a0808501919091527e0100000000000000000000000000000000000000000000000000000000000090920461ffff1660c084015260095460e0840152600a54610100840152600c5484517ffeaf968c00000000000000000000000000000000000000000000000000000000815294516000958694859490930473ffffffffffffffffffffffffffffffffffffffff169263feaf968c926004808401938290030181865afa158015612897573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128bb9190614eb2565b5093505092505080426128ce9190614da3565b836020015163ffffffff161080156128f057506000836020015163ffffffff16115b156129015750506101000151919050565b6000821361293e576040517f43d4cf6600000000000000000000000000000000000000000000000000000000815260048101839052602401610be1565b5092915050565b61294d612956565b6106c58161385f565b60005473ffffffffffffffffffffffffffffffffffffffff1633146129d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610be1565b565b600c546bffffffffffffffffffffffff166000036129f357565b60006129fd610ec5565b90508051600003612a3a576040517f30274b3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600c54600091612a59916bffffffffffffffffffffffff16614f02565b905060005b8251811015612b255781600b6000858481518110612a7e57612a7e614a77565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282829054906101000a90046bffffffffffffffffffffffff16612ae69190614f2d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080612b1e90614ad5565b9050612a5e565b508151612b329082614f52565b600c8054600090612b529084906bffffffffffffffffffffffff16614b0d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505050565b6129d7612956565b6000806006805480602002602001604051908101604052809291908181526020018280548015612bf257602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612bc7575b5050505050905060005b8151811015612c6b578373ffffffffffffffffffffffffffffffffffffffff16828281518110612c2e57612c2e614a77565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603612c5b575060019392505050565b612c6481614ad5565b9050612bfc565b5060009392505050565b600081806020019051810190612c8b9190614f82565b9050600081610100015113612cd5578061010001516040517f43d4cf66000000000000000000000000000000000000000000000000000000008152600401610be191815260200190565b80516008805460208401516040808601516060870151608088015160a089015160c08a015161ffff167e01000000000000000000000000000000000000000000000000000000000000027dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff69ffffffffffffffffffff90921674010000000000000000000000000000000000000000027fffff00000000000000000000ffffffffffffffffffffffffffffffffffffffff63ffffffff94851670010000000000000000000000000000000002167fffff0000000000000000000000000000ffffffffffffffffffffffffffffffff9585166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff9786166801000000000000000002979097167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff998616640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909b1695909c1694909417989098179690961698909817929092171617929092179390931692909217905560e0820151600955610100820151600a55517ffc10ed3768699b4370d710cd8ffbc7efdc5a691e42af93f2fe3d0ba7c335565890612ebc9083906144ee565b60405180910390a15050565b6000612ed5826020614d8c565b612ee0856020614d8c565b612eec8861014461502c565b612ef6919061502c565b612f00919061502c565b612f0b90600061502c565b9050368114612f76576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f63616c6c64617461206c656e677468206d69736d6174636800000000000000006044820152606401610be1565b50505050505050565b606080808080612f918688018861511a565b8451949950929750909550935091501580612fae57508351855114155b80612fbb57508251855114155b80612fc857508151855114155b80612fd557508051855114155b1561300c576040517f0be3632800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b855181101561313f5760006130a487838151811061302f5761302f614a77565b602002602001015187848151811061304957613049614a77565b602002602001015187858151811061306357613063614a77565b602002602001015187868151811061307d5761307d614a77565b602002602001015187878151811061309757613097614a77565b6020026020010151613954565b905060008160068111156130ba576130ba614b9c565b14806130d7575060018160068111156130d5576130d5614b9c565b145b1561312e578682815181106130ee576130ee614a77565b60209081029190910181015160405133815290917fc708e0440951fd63499c0f7a73819b469ee5dd3ecc356c0ab4eb7f18389009d9910160405180910390a25b5061313881614ad5565b905061300f565b505050505050505050505050565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810191909152604080516101208101825260085463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015269ffffffffffffffffffff7401000000000000000000000000000000000000000083041660a082015261ffff7e01000000000000000000000000000000000000000000000000000000000000909204821660c0820181905260095460e0830152600a546101008301529091851611156132ba576040517fdada758700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006132c686856105f4565b905060006132ee856040015186606001518469ffffffffffffffffffff1688608001516136d3565b905060007f000000000000000000000000000000000000000000000000000000000000000086516040517fa47c769600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015290915060009073ffffffffffffffffffffffffffffffffffffffff83169063a47c769690602401600060405180830381865afa158015613390573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526133d6919081019061525b565b9050826bffffffffffffffffffffffff16816040015182600001516133fb9190614b0d565b6bffffffffffffffffffffffff161015613441576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602087015187516040517f674603d000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff909116602482015260009184169063674603d090604401606060405180830381865afa1580156134c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ec919061532a565b50915050600061356f308a602001518b6000015185600161350d919061537c565b6040805173ffffffffffffffffffffffffffffffffffffffff958616602080830191909152949095168582015267ffffffffffffffff928316606086015291166080808501919091528151808503909101815260a09093019052815191012090565b90506040518061016001604052808a608001516bffffffffffffffffffffffff1681526020013073ffffffffffffffffffffffffffffffffffffffff1681526020018a6020015173ffffffffffffffffffffffffffffffffffffffff1681526020018a6000015167ffffffffffffffff1681526020018a6040015163ffffffff168152602001866bffffffffffffffffffffffff168152602001886080015163ffffffff164261361f919061502c565b64ffffffffff1681526020018281526020018769ffffffffffffffffffff168152602001886040015163ffffffff1664ffffffffff168152602001886060015163ffffffff1664ffffffffff1681525097508760405160200161368291906144df565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009384526007909252909120555050505050509392505050565b6008546000908190869061370b9063ffffffff6c01000000000000000000000000820481169168010000000000000000900416614de5565b6137159190614de5565b63ffffffff1690506000612710600860010154876137339190614d8c565b61373d919061539d565b613747908761502c565b9050600061375482613be8565b905060006137628483614d8c565b905060006137816bffffffffffffffffffffffff808916908a1661502c565b905061378d818361502c565b9a9950505050505050505050565b60006137a5610ec5565b511115610dba57610dba6129d9565b6000808a8a8a8a8a8a8a8a8a6040516020016137d8999897969594939291906153b1565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036138de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610be1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808380602001905181019061396b919061545b565b90508060405160200161397e91906144df565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008a81526007909352912054146139d0576006915050611cc4565b6000878152600760205260409020546139ed576002915050611cc4565b60006139f83a613be8565b90506000826101400151836101200151613a12919061552e565b613a239064ffffffffff1683614d8c565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a1d4c8288b8b8789610100015169ffffffffffffffffffff1688613a849190614f2d565b338b6040518763ffffffff1660e01b8152600401613aa79695949392919061554c565b60408051808303816000875af1158015613ac5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae991906155c8565b90925090506000826006811115613b0257613b02614b9c565b1480613b1f57506001826006811115613b1d57613b1d614b9c565b145b15613bda5760008b815260076020526040812055613b3d8184614f2d565b336000908152600b6020526040812080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff938416179055610100870151600c805469ffffffffffffffffffff90921693909291613bab91859116614f2d565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b509998505050505050505050565b6000613bf2612750565b613c0483670de0b6b3a7640000614d8c565b61061c919061539d565b508054613c1a90614768565b6000825580601f10613c2a575050565b601f0160209004906000526020600020908101906106c59190613c67565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115613c7c5760008155600101613c68565b5090565b60008083601f840112613c9257600080fd5b50813567ffffffffffffffff811115613caa57600080fd5b602083019150836020828501011115613cc257600080fd5b9250929050565b60008060208385031215613cdc57600080fd5b823567ffffffffffffffff811115613cf357600080fd5b613cff85828601613c80565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160a0810167ffffffffffffffff81118282101715613d5d57613d5d613d0b565b60405290565b6040516080810167ffffffffffffffff81118282101715613d5d57613d5d613d0b565b604051610120810167ffffffffffffffff81118282101715613d5d57613d5d613d0b565b60405160c0810167ffffffffffffffff81118282101715613d5d57613d5d613d0b565b604051610160810167ffffffffffffffff81118282101715613d5d57613d5d613d0b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613e3857613e38613d0b565b604052919050565b600082601f830112613e5157600080fd5b813567ffffffffffffffff811115613e6b57613e6b613d0b565b613e9c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601613df1565b818152846020838601011115613eb157600080fd5b816020850160208301376000918101602001919091529392505050565b67ffffffffffffffff811681146106c557600080fd5b80356110e081613ece565b73ffffffffffffffffffffffffffffffffffffffff811681146106c557600080fd5b63ffffffff811681146106c557600080fd5b6bffffffffffffffffffffffff811681146106c557600080fd5b60008082840360c0811215613f5157600080fd5b833567ffffffffffffffff811115613f6857600080fd5b613f7486828701613e40565b93505060a07fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe082011215613fa757600080fd5b50613fb0613d3a565b6020840135613fbe81613ece565b81526040840135613fce81613eef565b60208201526060840135613fe181613f11565b60408201526080840135606082015260a0840135613ffe81613f23565b6080820152919491935090915050565b6000815180845260005b8181101561403457602081850181015186830182015201614018565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000614085602083018461400e565b9392505050565b60006020828403121561409e57600080fd5b813561408581613eef565b600081518084526020808501945080840160005b838110156140ef57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016140bd565b509495945050505050565b60408152600061410d60408301856140a9565b6020838203818501528185518084528284019150828160051b85010183880160005b8381101561417b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe087840301855261416983835161400e565b9486019492509085019060010161412f565b50909998505050505050505050565b6000806040838503121561419d57600080fd5b82356141a881613eef565b915060208301356141b881613f23565b809150509250929050565b6000806000604084860312156141d857600080fd5b83356141e381613eef565b9250602084013567ffffffffffffffff8111156141ff57600080fd5b61420b86828701613c80565b9497909650939450505050565b60208152600061408560208301846140a9565b60006020828403121561423d57600080fd5b5035919050565b60006020828403121561425657600080fd5b813567ffffffffffffffff81111561426d57600080fd5b61427984828501613e40565b949350505050565b60008083601f84011261429357600080fd5b50813567ffffffffffffffff8111156142ab57600080fd5b6020830191508360208260051b8501011115613cc257600080fd5b60008060008060008060008060e0898b0312156142e257600080fd5b606089018a8111156142f357600080fd5b8998503567ffffffffffffffff8082111561430d57600080fd5b6143198c838d01613c80565b909950975060808b013591508082111561433257600080fd5b61433e8c838d01614281565b909750955060a08b013591508082111561435757600080fd5b506143648b828c01614281565b999c989b50969995989497949560c00135949350505050565b60006020828403121561438f57600080fd5b813567ffffffffffffffff8111156143a657600080fd5b8201610100818503121561408557600080fd5b80516bffffffffffffffffffffffff16825260208101516143f2602084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604081015161441a604084018273ffffffffffffffffffffffffffffffffffffffff169052565b506060810151614436606084018267ffffffffffffffff169052565b50608081015161444e608084018263ffffffff169052565b5060a081015161446e60a08401826bffffffffffffffffffffffff169052565b5060c081015161448760c084018264ffffffffff169052565b5060e081015160e0830152610100808201516144b08285018269ffffffffffffffffffff169052565b50506101208181015164ffffffffff81168483015250506101408181015164ffffffffff811684830152610ebf565b610160810161061c82846143b9565b815163ffffffff9081168252602080840151821690830152604080840151821690830152606080840151821690830152608080840151918216908301526101208201905060a083015161454f60a084018269ffffffffffffffffffff169052565b5060c083015161456560c084018261ffff169052565b5060e083015160e083015261010080840151818401525092915050565b60008060008060006080868803121561459a57600080fd5b85356145a581613ece565b9450602086013567ffffffffffffffff8111156145c157600080fd5b6145cd88828901613c80565b90955093505060408601356145e181613f11565b949793965091946060013592915050565b600067ffffffffffffffff82111561460c5761460c613d0b565b5060051b60200190565b600082601f83011261462757600080fd5b8135602061463c614637836145f2565b613df1565b82815260059290921b8401810191818101908684111561465b57600080fd5b8286015b8481101561467f57803561467281613eef565b835291830191830161465f565b509695505050505050565b803560ff811681146110e057600080fd5b60008060008060008060c087890312156146b457600080fd5b863567ffffffffffffffff808211156146cc57600080fd5b6146d88a838b01614616565b975060208901359150808211156146ee57600080fd5b6146fa8a838b01614616565b965061470860408a0161468a565b9550606089013591508082111561471e57600080fd5b61472a8a838b01613e40565b945061473860808a01613ee4565b935060a089013591508082111561474e57600080fd5b5061475b89828a01613e40565b9150509295509295509295565b600181811c9082168061477c57607f821691505b6020821081036147b5577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b601f8211156105ef57600081815260208120601f850160051c810160208610156147e25750805b601f850160051c820191505b81811015610b5c578281556001016147ee565b67ffffffffffffffff83111561481957614819613d0b565b61482d836148278354614768565b836147bb565b6000601f84116001811461487f57600085156148495750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355614915565b6000838152602090207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0861690835b828110156148ce57868501358255602094850194600190920191016148ae565b5086821015614909577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61ffff811681146106c557600080fd5b80516110e08161491c565b80516110e081613f23565b80516110e081613f11565b6000602080838503121561496057600080fd5b825167ffffffffffffffff8082111561497857600080fd5b908401906080828703121561498c57600080fd5b614994613d63565b825161499f8161491c565b8152828401516149ae81613f23565b8185015260408301517fffffffff00000000000000000000000000000000000000000000000000000000811681146149e557600080fd5b60408201526060830151828111156149fc57600080fd5b80840193505086601f840112614a1157600080fd5b82519150614a21614637836145f2565b82815260059290921b83018401918481019088841115614a4057600080fd5b938501935b83851015614a67578451614a5881613f11565b82529385019390850190614a45565b6060830152509695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614b0657614b06614aa6565b5060010190565b6bffffffffffffffffffffffff82811682821603908082111561293e5761293e614aa6565b60ff818116838216019081111561061c5761061c614aa6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600060ff831680614b8d57614b8d614b4b565b8060ff84160491505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8183823760009101908152919050565b828152606082602083013760800192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112614c2457600080fd5b83018035915067ffffffffffffffff821115614c3f57600080fd5b602001915036819003821315613cc257600080fd5b600060208284031215614c6657600080fd5b813561408581613ece565b600060208284031215614c8357600080fd5b813561408581613f11565b600060208284031215614ca057600080fd5b813561408581613f23565b600060208284031215614cbd57600080fd5b81356140858161491c565b73ffffffffffffffffffffffffffffffffffffffff8a8116825267ffffffffffffffff8a16602083015288166040820152610100606082018190528101869052600061012087898285013760008189850101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f890116830161ffff881660808501528660a0850152614d6560c085018763ffffffff169052565b818482030160e0850152614d7b8282018661400e565b9d9c50505050505050505050505050565b808202811582820484141761061c5761061c614aa6565b8181038181111561061c5761061c614aa6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b63ffffffff81811683821601908082111561293e5761293e614aa6565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152614e328184018a6140a9565b90508281036080840152614e4681896140a9565b905060ff871660a084015282810360c0840152614e63818761400e565b905067ffffffffffffffff851660e0840152828103610100840152614e88818561400e565b9c9b505050505050505050505050565b805169ffffffffffffffffffff811681146110e057600080fd5b600080600080600060a08688031215614eca57600080fd5b614ed386614e98565b9450602086015193506040860151925060608601519150614ef660808701614e98565b90509295509295909350565b60006bffffffffffffffffffffffff80841680614f2157614f21614b4b565b92169190910492915050565b6bffffffffffffffffffffffff81811683821601908082111561293e5761293e614aa6565b6bffffffffffffffffffffffff818116838216028082169190828114614f7a57614f7a614aa6565b505092915050565b60006101208284031215614f9557600080fd5b614f9d613d86565b614fa683614942565b8152614fb460208401614942565b6020820152614fc560408401614942565b6040820152614fd660608401614942565b6060820152614fe760808401614942565b6080820152614ff860a08401614e98565b60a082015261500960c0840161492c565b60c082015260e08381015190820152610100928301519281019290925250919050565b8082018082111561061c5761061c614aa6565b600082601f83011261505057600080fd5b81356020615060614637836145f2565b82815260059290921b8401810191818101908684111561507f57600080fd5b8286015b8481101561467f5780358352918301918301615083565b600082601f8301126150ab57600080fd5b813560206150bb614637836145f2565b82815260059290921b840181019181810190868411156150da57600080fd5b8286015b8481101561467f57803567ffffffffffffffff8111156150fe5760008081fd5b61510c8986838b0101613e40565b8452509183019183016150de565b600080600080600060a0868803121561513257600080fd5b853567ffffffffffffffff8082111561514a57600080fd5b61515689838a0161503f565b9650602088013591508082111561516c57600080fd5b61517889838a0161509a565b9550604088013591508082111561518e57600080fd5b61519a89838a0161509a565b945060608801359150808211156151b057600080fd5b6151bc89838a0161509a565b935060808801359150808211156151d257600080fd5b506151df8882890161509a565b9150509295509295909350565b80516110e081613eef565b600082601f83011261520857600080fd5b81516020615218614637836145f2565b82815260059290921b8401810191818101908684111561523757600080fd5b8286015b8481101561467f57805161524e81613eef565b835291830191830161523b565b60006020828403121561526d57600080fd5b815167ffffffffffffffff8082111561528557600080fd5b9083019060c0828603121561529957600080fd5b6152a1613daa565b82516152ac81613f23565b815260208301516152bc81613eef565b602082015260408301516152cf81613f23565b60408201526152e0606084016151ec565b60608201526080830151828111156152f757600080fd5b615303878286016151f7565b60808301525060a083015160a082015280935050505092915050565b80516110e081613ece565b60008060006060848603121561533f57600080fd5b8351801515811461534f57600080fd5b602085015190935061536081613ece565b604085015190925061537181613ece565b809150509250925092565b67ffffffffffffffff81811683821601908082111561293e5761293e614aa6565b6000826153ac576153ac614b4b565b500490565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526153f88285018b6140a9565b9150838203608085015261540c828a6140a9565b915060ff881660a085015283820360c0850152615429828861400e565b90861660e08501528381036101008501529050614e88818561400e565b805164ffffffffff811681146110e057600080fd5b6000610160828403121561546e57600080fd5b615476613dcd565b61547f83614937565b815261548d602084016151ec565b602082015261549e604084016151ec565b60408201526154af6060840161531f565b60608201526154c060808401614942565b60808201526154d160a08401614937565b60a08201526154e260c08401615446565b60c082015260e083015160e08201526101006154ff818501614e98565b90820152610120615511848201615446565b90820152610140615523848201615446565b908201529392505050565b64ffffffffff81811683821601908082111561293e5761293e614aa6565b60006102008083526155608184018a61400e565b90508281036020840152615574818961400e565b6bffffffffffffffffffffffff88811660408601528716606085015273ffffffffffffffffffffffffffffffffffffffff8616608085015291506155bd905060a08301846143b9565b979650505050505050565b600080604083850312156155db57600080fd5b8251600781106155ea57600080fd5b60208401519092506141b881613f2356fea164736f6c6343000813000a", } var FunctionsCoordinatorABI = FunctionsCoordinatorMetaData.ABI @@ -204,9 +216,9 @@ func (_FunctionsCoordinator *FunctionsCoordinatorTransactorRaw) Transact(opts *b return _FunctionsCoordinator.Contract.contract.Transact(opts, method, params...) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "estimateCost", subscriptionId, data, callbackGasLimit, gasPrice) + err := _FunctionsCoordinator.contract.Call(opts, &out, "estimateCost", subscriptionId, data, callbackGasLimit, gasPriceGwei) if err != nil { return *new(*big.Int), err @@ -218,12 +230,12 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCaller) EstimateCost(opts *bind } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) { - return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPrice) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) { + return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceGwei) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) { - return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPrice) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) EstimateCost(subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) { + return _FunctionsCoordinator.Contract.EstimateCost(&_FunctionsCoordinator.CallOpts, subscriptionId, data, callbackGasLimit, gasPriceGwei) } func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetAdminFee(opts *bind.CallOpts) (*big.Int, error) { @@ -271,41 +283,25 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetAllNodePublic return _FunctionsCoordinator.Contract.GetAllNodePublicKeys(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetConfig(opts *bind.CallOpts) (GetConfig, - - error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetConfig(opts *bind.CallOpts) (IFunctionsBillingConfig, error) { var out []interface{} err := _FunctionsCoordinator.contract.Call(opts, &out, "getConfig") - outstruct := new(GetConfig) if err != nil { - return *outstruct, err + return *new(IFunctionsBillingConfig), err } - outstruct.MaxCallbackGasLimit = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.FeedStalenessSeconds = *abi.ConvertType(out[1], new(uint32)).(*uint32) - outstruct.GasOverheadBeforeCallback = *abi.ConvertType(out[2], new(uint32)).(*uint32) - outstruct.GasOverheadAfterCallback = *abi.ConvertType(out[3], new(uint32)).(*uint32) - outstruct.RequestTimeoutSeconds = *abi.ConvertType(out[4], new(uint32)).(*uint32) - outstruct.DonFee = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) - outstruct.MaxSupportedRequestDataVersion = *abi.ConvertType(out[6], new(uint16)).(*uint16) - outstruct.FulfillmentGasPriceOverEstimationBP = *abi.ConvertType(out[7], new(*big.Int)).(**big.Int) - outstruct.FallbackNativePerUnitLink = *abi.ConvertType(out[8], new(*big.Int)).(**big.Int) - outstruct.LinkPriceFeed = *abi.ConvertType(out[9], new(common.Address)).(*common.Address) + out0 := *abi.ConvertType(out[0], new(IFunctionsBillingConfig)).(*IFunctionsBillingConfig) - return *outstruct, err + return out0, err } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetConfig() (GetConfig, - - error) { +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetConfig() (IFunctionsBillingConfig, error) { return _FunctionsCoordinator.Contract.GetConfig(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetConfig() (GetConfig, - - error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetConfig() (IFunctionsBillingConfig, error) { return _FunctionsCoordinator.Contract.GetConfig(&_FunctionsCoordinator.CallOpts) } @@ -353,48 +349,48 @@ func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetDONPublicKey( return _FunctionsCoordinator.Contract.GetDONPublicKey(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetFeedData(opts *bind.CallOpts) (*big.Int, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getFeedData") + err := _FunctionsCoordinator.contract.Call(opts, &out, "getThresholdPublicKey") if err != nil { - return *new(*big.Int), err + return *new([]byte), err } - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) return out0, err } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetFeedData() (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetFeedData(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetThresholdPublicKey() ([]byte, error) { + return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetFeedData() (*big.Int, error) { - return _FunctionsCoordinator.Contract.GetFeedData(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetThresholdPublicKey() ([]byte, error) { + return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) { +func (_FunctionsCoordinator *FunctionsCoordinatorCaller) GetWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _FunctionsCoordinator.contract.Call(opts, &out, "getThresholdPublicKey") + err := _FunctionsCoordinator.contract.Call(opts, &out, "getWeiPerUnitLink") if err != nil { - return *new([]byte), err + return *new(*big.Int), err } - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) return out0, err } -func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetThresholdPublicKey() ([]byte, error) { - return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorSession) GetWeiPerUnitLink() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetWeiPerUnitLink(&_FunctionsCoordinator.CallOpts) } -func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetThresholdPublicKey() ([]byte, error) { - return _FunctionsCoordinator.Contract.GetThresholdPublicKey(&_FunctionsCoordinator.CallOpts) +func (_FunctionsCoordinator *FunctionsCoordinatorCallerSession) GetWeiPerUnitLink() (*big.Int, error) { + return _FunctionsCoordinator.Contract.GetWeiPerUnitLink(&_FunctionsCoordinator.CallOpts) } func (_FunctionsCoordinator *FunctionsCoordinatorCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, @@ -573,6 +569,18 @@ func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) OracleWithdr return _FunctionsCoordinator.Contract.OracleWithdraw(&_FunctionsCoordinator.TransactOpts, recipient, amount) } +func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) OracleWithdrawAll(opts *bind.TransactOpts) (*types.Transaction, error) { + return _FunctionsCoordinator.contract.Transact(opts, "oracleWithdrawAll") +} + +func (_FunctionsCoordinator *FunctionsCoordinatorSession) OracleWithdrawAll() (*types.Transaction, error) { + return _FunctionsCoordinator.Contract.OracleWithdrawAll(&_FunctionsCoordinator.TransactOpts) +} + +func (_FunctionsCoordinator *FunctionsCoordinatorTransactorSession) OracleWithdrawAll() (*types.Transaction, error) { + return _FunctionsCoordinator.Contract.OracleWithdrawAll(&_FunctionsCoordinator.TransactOpts) +} + func (_FunctionsCoordinator *FunctionsCoordinatorTransactor) SendRequest(opts *bind.TransactOpts, request IFunctionsCoordinatorRequest) (*types.Transaction, error) { return _FunctionsCoordinator.contract.Transact(opts, "sendRequest", request) } @@ -847,16 +855,8 @@ func (it *FunctionsCoordinatorConfigChangedIterator) Close() error { } type FunctionsCoordinatorConfigChanged struct { - MaxCallbackGasLimit uint32 - FeedStalenessSeconds uint32 - GasOverheadBeforeCallback uint32 - GasOverheadAfterCallback uint32 - RequestTimeoutSeconds uint32 - DonFee *big.Int - MaxSupportedRequestDataVersion uint16 - FulfillmentGasPriceOverEstimationBP *big.Int - FallbackNativePerUnitLink *big.Int - Raw types.Log + Config IFunctionsBillingConfig + Raw types.Log } func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*FunctionsCoordinatorConfigChangedIterator, error) { @@ -1698,18 +1698,6 @@ func (_FunctionsCoordinator *FunctionsCoordinatorFilterer) ParseTransmitted(log return event, nil } -type GetConfig struct { - MaxCallbackGasLimit uint32 - FeedStalenessSeconds uint32 - GasOverheadBeforeCallback uint32 - GasOverheadAfterCallback uint32 - RequestTimeoutSeconds uint32 - DonFee *big.Int - MaxSupportedRequestDataVersion uint16 - FulfillmentGasPriceOverEstimationBP *big.Int - FallbackNativePerUnitLink *big.Int - LinkPriceFeed common.Address -} type LatestConfigDetails struct { ConfigCount uint32 BlockNumber uint32 @@ -1750,7 +1738,7 @@ func (FunctionsCoordinatorCommitmentDeleted) Topic() common.Hash { } func (FunctionsCoordinatorConfigChanged) Topic() common.Hash { - return common.HexToHash("0x3332571032ee658b30d567e63b2443e9d921162625e0f3fe86968a586c1a090f") + return common.HexToHash("0xfc10ed3768699b4370d710cd8ffbc7efdc5a691e42af93f2fe3d0ba7c3355658") } func (FunctionsCoordinatorConfigSet) Topic() common.Hash { @@ -1782,24 +1770,22 @@ func (_FunctionsCoordinator *FunctionsCoordinator) Address() common.Address { } type FunctionsCoordinatorInterface interface { - EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPrice *big.Int) (*big.Int, error) + EstimateCost(opts *bind.CallOpts, subscriptionId uint64, data []byte, callbackGasLimit uint32, gasPriceGwei *big.Int) (*big.Int, error) GetAdminFee(opts *bind.CallOpts) (*big.Int, error) GetAllNodePublicKeys(opts *bind.CallOpts) ([]common.Address, [][]byte, error) - GetConfig(opts *bind.CallOpts) (GetConfig, - - error) + GetConfig(opts *bind.CallOpts) (IFunctionsBillingConfig, error) GetDONFee(opts *bind.CallOpts, arg0 []byte, arg1 IFunctionsBillingRequestBilling) (*big.Int, error) GetDONPublicKey(opts *bind.CallOpts) ([]byte, error) - GetFeedData(opts *bind.CallOpts) (*big.Int, error) - GetThresholdPublicKey(opts *bind.CallOpts) ([]byte, error) + GetWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, error) @@ -1822,6 +1808,8 @@ type FunctionsCoordinatorInterface interface { OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) + OracleWithdrawAll(opts *bind.TransactOpts) (*types.Transaction, error) + SendRequest(opts *bind.TransactOpts, request IFunctionsCoordinatorRequest) (*types.Transaction, error) SetConfig(opts *bind.TransactOpts, _signers []common.Address, _transmitters []common.Address, _f uint8, _onchainConfig []byte, _offchainConfigVersion uint64, _offchainConfig []byte) (*types.Transaction, error) diff --git a/core/gethwrappers/functions/generated/functions_router/functions_router.go b/core/gethwrappers/functions/generated/functions_router/functions_router.go index d8fdda01af4..3b27060d6cb 100644 --- a/core/gethwrappers/functions/generated/functions_router/functions_router.go +++ b/core/gethwrappers/functions/generated/functions_router/functions_router.go @@ -44,16 +44,32 @@ type FunctionsResponseCommitment struct { GasOverheadAfterCallback *big.Int } +type IFunctionsRouterConfig struct { + MaxConsumersPerSubscription uint16 + AdminFee *big.Int + HandleOracleFulfillmentSelector [4]byte + MaxCallbackGasLimits []uint32 +} + +type IFunctionsSubscriptionsSubscription struct { + Balance *big.Int + Owner common.Address + BlockedBalance *big.Int + ProposedOwner common.Address + Consumers []common.Address + Flags [32]byte +} + var FunctionsRouterMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"timelockBlocks\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"maximumTimelockBlocks\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConsumerRequestsInFlight\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"limit\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"IdentifierIsReserved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"value\",\"type\":\"uint8\"}],\"name\":\"InvalidGasFlagValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeSubscriptionOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRoute\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ProposedTimelockAboveMaximum\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderMustAcceptTermsOfService\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimelockInEffect\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"indexed\":false,\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"toBytes\",\"type\":\"bytes\"}],\"name\":\"ConfigProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"toBytes\",\"type\":\"bytes\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"timelockEndBlock\",\"type\":\"uint64\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"RequestNotProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"RequestProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"from\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"to\",\"type\":\"uint16\"}],\"name\":\"TimeLockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"from\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"to\",\"type\":\"uint16\"}],\"name\":\"TimeLockUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_RETURN_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutCallback\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"uint40\",\"name\":\"timeoutTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint80\",\"name\":\"donFee\",\"type\":\"uint80\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getFlags\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getProposedContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timelockEndBlock\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"ids\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"to\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"requestedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"isValidCallbackGasLimit\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"proposeConfigUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"proposeConfigUpdateSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"proposeSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"blocks\",\"type\":\"uint16\"}],\"name\":\"proposeTimelockBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestToProposed\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"name\":\"setFlags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"uint40\",\"name\":\"timeoutTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint80\",\"name\":\"donFee\",\"type\":\"uint80\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"}],\"internalType\":\"structFunctionsResponse.Commitment[]\",\"name\":\"requestsToTimeoutByCommitment\",\"type\":\"tuple[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateConfigSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateTimelockBlocks\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b50604051620066bd380380620066bd833981016040819052620000349162000441565b6000805460ff191681558290339086908690859084908190816200009f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000d957620000d9816200016e565b50506007805461ffff80871661ffff19909216919091179091558316608052506000805260026020527fac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c89077b80546001600160a01b031916301790556200013e816200021f565b5050600a80546001600160a01b0319166001600160a01b03949094169390931790925550620006cd945050505050565b336001600160a01b03821603620001c85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000096565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929361010090910416917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600080600080848060200190518101906200023b91906200053e565b6040805160808101825261ffff86168082526001600160601b03861660208084018290526001600160e01b031987169484019490945260608301859052600f80546001600160701b031916909217620100009091021763ffffffff60701b1916600160701b60e087901c021781558351969a509498509296509094509092620002cb916010919086019062000313565b509050507fe6a1eda76d42a6d1d813f26765716562044db1e8bd8be7d088705e64afd301ca83838360405162000304939291906200065c565b60405180910390a15050505050565b82805482825590600052602060002090600701600890048101928215620003b75791602002820160005b838211156200038357835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026200033d565b8015620003b55782816101000a81549063ffffffff021916905560040160208160030104928301926001030262000383565b505b50620003c5929150620003c9565b5090565b5b80821115620003c55760008155600101620003ca565b805161ffff81168114620003f357600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715620004395762000439620003f8565b604052919050565b600080600080608085870312156200045857600080fd5b6200046385620003e0565b9350602062000474818701620003e0565b60408701519094506001600160a01b03811681146200049257600080fd5b60608701519093506001600160401b0380821115620004b057600080fd5b818801915088601f830112620004c557600080fd5b815181811115620004da57620004da620003f8565b620004ee601f8201601f191685016200040e565b915080825289848285010111156200050557600080fd5b60005b818110156200052557838101850151838201860152840162000508565b5060008482840101525080935050505092959194509250565b600080600080608085870312156200055557600080fd5b6200056085620003e0565b602086810151919550906001600160601b03811681146200058057600080fd5b60408701519094506001600160e01b0319811681146200059f57600080fd5b60608701519093506001600160401b0380821115620005bd57600080fd5b818801915088601f830112620005d257600080fd5b815181811115620005e757620005e7620003f8565b8060051b9150620005fa8483016200040e565b818152918301840191848101908b8411156200061557600080fd5b938501935b838510156200064c578451925063ffffffff831683146200063b5760008081fd5b82825293850193908501906200061a565b989b979a50959850505050505050565b6001600160601b03841681526001600160e01b031983166020808301919091526060604083018190528351908301819052600091848101916080850190845b81811015620006bf57845163ffffffff16835293830193918301916001016200069b565b509098975050505050505050565b608051615fd4620006e96000396000612ab70152615fd46000f3fe608060405234801561001057600080fd5b50600436106102f45760003560e01c806379ba509711610191578063aab396bd116100e3578063d7ae1d3011610097578063ea5d840f11610071578063ea5d840f14610756578063eb523d6c14610769578063f2fde38b1461077c57600080fd5b8063d7ae1d301461071d578063e72f6e3014610730578063e82ad7d41461074357600080fd5b8063b734c0f4116100c8578063b734c0f4146106e6578063badc3eb6146106ee578063c3f909d41461070557600080fd5b8063aab396bd146106ad578063b5643858146106d357600080fd5b80639f87fad711610145578063a47c76961161011f578063a47c769614610662578063a4c0ed3614610687578063a9c9a9181461069a57600080fd5b80639f87fad714610626578063a1d4c82814610639578063a21a23e41461065a57600080fd5b80638456cb59116101765780638456cb59146105f35780638da5cb5b146105fb5780638fde53171461061e57600080fd5b806379ba5097146105d857806382359740146105e057600080fd5b8063461d27621161024a57806366316d8d116101fe5780636a2215de116101d85780636a2215de1461057a5780636e3b3323146105b25780637341c10c146105c557600080fd5b806366316d8d146104ab57806366419970146104be578063674603d0146104e557600080fd5b806355fedefa1161022f57806355fedefa146104545780635c975abb146104815780635ed6dfba1461049857600080fd5b8063461d27621461042e5780634b8832d31461044157600080fd5b80631c024539116102ac5780633e871e4d116102865780633e871e4d146103f25780633f4ba83a1461040557806341db4ca31461040d57600080fd5b80631c024539146103c45780631ded3b36146103cc578063385de9ae146103df57600080fd5b806310fc49c1116102dd57806310fc49c11461032e57806312b5834914610341578063181f5a771461037b57600080fd5b806302bcc5b6146102f95780630c5d49cb1461030e575b600080fd5b61030c610307366004614ace565b61078f565b005b610316608481565b60405161ffff90911681526020015b60405180910390f35b61030c61033c366004614b0f565b6107ee565b6009546801000000000000000090046bffffffffffffffffffffffff166040516bffffffffffffffffffffffff9091168152602001610325565b6103b76040518060400160405280601781526020017f46756e6374696f6e7320526f757465722076312e302e3000000000000000000081525081565b6040516103259190614bac565b61030c6108ea565b61030c6103da366004614bbf565b610a5b565b61030c6103ed366004614c34565b610a8c565b61030c610400366004614ded565b610b95565b61030c610ed6565b61042061041b366004614eb6565b610ee8565b604051908152602001610325565b61042061043c366004614eb6565b610f48565b61030c61044f366004614f3b565b610f54565b610420610462366004614ace565b67ffffffffffffffff166000908152600b602052604090206003015490565b60005460ff165b6040519015158152602001610325565b61030c6104a6366004614f8e565b611052565b61030c6104b9366004614f8e565b611325565b60095467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610325565b6105526104f3366004614fbc565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600c6020908152604080832067ffffffffffffffff948516845290915290205460ff8116926101008204831692690100000000000000000090920490911690565b60408051931515845267ffffffffffffffff9283166020850152911690820152606001610325565b61058d610588366004614fea565b61154c565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610325565b61030c6105c0366004615003565b61160b565b61030c6105d3366004614f3b565b6118e7565b61030c611a7d565b61030c6105ee366004614ace565b611b9f565b61030c611ccd565b600054610100900473ffffffffffffffffffffffffffffffffffffffff1661058d565b61030c611cdd565b61030c610634366004614f3b565b611d71565b61064c61064736600461521c565b612146565b604051610325929190615304565b6104cc61253a565b610675610670366004614ace565b6126c7565b6040516103259695949392919061537e565b61030c6106953660046153e8565b6127d7565b61058d6106a8366004614fea565b612a06565b7fd8e0666292c202b1ce6a8ff0dd638652e662402ac53fbf9bd9d3bcc39d5eb097610420565b61030c6106e1366004615444565b612a6b565b61030c612bd4565b6106f6612d8e565b60405161032593929190615461565b61070d612e67565b60405161032594939291906154ec565b61030c61072b366004614f3b565b612f1e565b61030c61073e36600461554f565b612f81565b610488610751366004614ace565b613189565b61030c61076436600461556c565b6132d8565b61030c610777366004614fea565b6133fe565b61030c61078a36600461554f565b6135c9565b6107976135da565b6107a0816135e2565b67ffffffffffffffff81166000908152600b60205260409020546107eb9082906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16613658565b50565b67ffffffffffffffff82166000908152600b6020526040812060030154601054911a908110610853576040517f45c108ce00000000000000000000000000000000000000000000000000000000815260ff821660048201526024015b60405180910390fd5b6000600f6001018260ff168154811061086e5761086e6155ae565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1690508063ffffffff168363ffffffff1611156108e4576040517f1d70f87a00000000000000000000000000000000000000000000000000000000815263ffffffff8216600482015260240161084a565b50505050565b6108f26139bd565b60008080526006602052604080518082019091527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f8805482908290610936906155dd565b80601f0160208091040260200160405190810160405280929190818152602001828054610962906155dd565b80156109af5780601f10610984576101008083540402835291602001916109af565b820191906000526020600020905b81548152906001019060200180831161099257829003601f168201915b50505091835250506001919091015467ffffffffffffffff9081166020928301529082015191925016431015610a11576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051610a1c90613a43565b80516040517fd97d1d65f3cae3537cf4c61e688583d89aae53d8b32accdfe7cb189e65ef34c791610a509160009190615630565b60405180910390a150565b610a636135da565b610a6c826135e2565b67ffffffffffffffff9091166000908152600b6020526040902060030155565b610a946139bd565b6040805160606020601f85018190040282018101835291810183815290918291908590859081908501838280828437600092019190915250505090825250600754602090910190610ae99061ffff1643615680565b67ffffffffffffffff169052600084815260066020526040902081518190610b1190826156e1565b5060209190910151600190910180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9092169190911790556040517fdf3b58e133a3ba6c2ac90fe2b70fef7f7d69dd675fe9c542a6f0fe2f3a8a6f3a90610b88908590859085906157fb565b60405180910390a1505050565b610b9d6139bd565b8151815181141580610baf5750600881115b15610be6576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610d12576000848281518110610c0557610c056155ae565b602002602001015190506000848381518110610c2357610c236155ae565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610c8e575060008281526002602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610cc5576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81610cff576040517f4855c2880000000000000000000000000000000000000000000000000000000081526004810183905260240161084a565b505080610d0b9061584f565b9050610be9565b50600754600090610d279061ffff1643615680565b60408051606081018252868152602080820187905267ffffffffffffffff841692820192909252865192935091600391610d6591839189019061490e565b506020828101518051610d7e9260018501920190614955565b5060409190910151600290910180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff90921691909117905560005b8451811015610ecf577fbb4a5564503edfa78c35ff85fcc767ab37e97bd74f243e78b582b292671c004e858281518110610e0057610e006155ae565b602002602001015160026000888581518110610e1e57610e1e6155ae565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868481518110610e6757610e676155ae565b602002602001015185604051610eb7949392919093845273ffffffffffffffffffffffffffffffffffffffff92831660208501529116604083015267ffffffffffffffff16606082015260800190565b60405180910390a1610ec88161584f565b9050610dc4565b5050505050565b610ede6139bd565b610ee6613b89565b565b600080610ef48361154c565b9050610f3c83828a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b9150613c069050565b98975050505050505050565b600080610ef483612a06565b610f5c613f56565b610f6582613f5e565b610f6d614024565b67ffffffffffffffff82166000908152600b602052604090206001015473ffffffffffffffffffffffffffffffffffffffff8281166c01000000000000000000000000909204161461104e5767ffffffffffffffff82166000818152600b602090815260409182902060010180546bffffffffffffffffffffffff166c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8716908102919091179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be91015b60405180910390a25b5050565b61105a6135da565b806bffffffffffffffffffffffff166000036110905750306000908152600d60205260409020546bffffffffffffffffffffffff165b306000908152600d60205260409020546bffffffffffffffffffffffff808316911610156110ea576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b306000908152600d6020526040812080548392906111179084906bffffffffffffffffffffffff16615887565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080600960088282829054906101000a90046bffffffffffffffffffffffff1661116e9190615887565b82546101009290920a6bffffffffffffffffffffffff818102199093169183160217909155600a546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015292851660248201529116915063a9059cbb906044016020604051808303816000875af115801561120d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123191906158b3565b61104e57600a546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156112a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c891906158d5565b6009546040517fa99da302000000000000000000000000000000000000000000000000000000008152680100000000000000009091046bffffffffffffffffffffffff16600482018190526024820183905291925060440161084a565b61132d613f56565b806bffffffffffffffffffffffff16600003611375576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600d60205260409020546bffffffffffffffffffffffff808316911610156113cf576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600d6020526040812080548392906113fc9084906bffffffffffffffffffffffff16615887565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080600960088282829054906101000a90046bffffffffffffffffffffffff166114539190615887565b82546101009290920a6bffffffffffffffffffffffff818102199093169183160217909155600a546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff868116600483015292851660248201529116915063a9059cbb906044016020604051808303816000875af11580156114f2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151691906158b3565b61104e576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000805b60035460ff821610156115d5576003805460ff8316908110611574576115746155ae565b906000526020600020015483036115c5576004805460ff831690811061159c5761159c6155ae565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b6115ce816158ee565b9050611550565b506040517f80833e330000000000000000000000000000000000000000000000000000000081526004810183905260240161084a565b611613613f56565b60005b818110156118e2576000838383818110611632576116326155ae565b90506101600201803603810190611649919061590d565b905060008160e001519050600082606001519050600e60008381526020019081526020016000205483604051602001611682919061592a565b60405160208183030381529060405280519060200120146116cf576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c0015164ffffffffff16421015611714576040517fbcc4005500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116906385b214cf906024016020604051808303816000875af1158015611787573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ab91906158b3565b5060a083015167ffffffffffffffff82166000908152600b6020526040812060010180549091906117eb9084906bffffffffffffffffffffffff16615887565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555060408084015173ffffffffffffffffffffffffffffffffffffffff166000908152600c602090815282822067ffffffffffffffff8086168452915291902080546001926009916118729185916901000000000000000000900416615a59565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000828152600e60205260408082208290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a2505050806118db9061584f565b9050611616565b505050565b6118ef613f56565b6118f882613f5e565b611900614024565b600f5467ffffffffffffffff83166000908152600b602052604090206002015461ffff909116900361195e576040517f05a48e0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166000908152600c6020908152604080832067ffffffffffffffff8616845290915290205460ff16156119a5575050565b73ffffffffffffffffffffffffffffffffffffffff81166000818152600c6020908152604080832067ffffffffffffffff871680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600b84528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09101611045565b60015473ffffffffffffffffffffffffffffffffffffffff163314611afe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161084a565b60008054336101008181027fffffffffffffffffffffff0000000000000000000000000000000000000000ff8416178455600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905560405173ffffffffffffffffffffffffffffffffffffffff919093041692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611ba7613f56565b611baf614024565b67ffffffffffffffff81166000908152600b60205260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000092839004811692909104163314611c36576040517f02b543c600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000818152600b602090815260409182902080546c01000000000000000000000000339081026bffffffffffffffffffffffff928316178355600190920180549091169055825173ffffffffffffffffffffffffffffffffffffffff86168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f09101611045565b611cd56139bd565b610ee6614129565b611ce56139bd565b600854640100000000900467ffffffffffffffff16431015611d33576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600854600780546201000090920461ffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216919091179055565b611d79613f56565b611d8282613f5e565b611d8a614024565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600c6020908152604080832067ffffffffffffffff8087168552908352928190208151606081018352905460ff8116151580835261010082048616948301949094526901000000000000000000900490931690830152611e32576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614611e87576040517fbcc4005500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff83166000908152600b6020908152604080832060020180548251818502810185019093528083529192909190830182828015611f0257602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611ed7575b5050505050905060005b81518110156120aa578373ffffffffffffffffffffffffffffffffffffffff16828281518110611f3e57611f3e6155ae565b602002602001015173ffffffffffffffffffffffffffffffffffffffff160361209a578160018351611f709190615a7a565b81518110611f8057611f806155ae565b6020026020010151600b60008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018281548110611fc357611fc36155ae565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff87168152600b9091526040902060020180548061203d5761203d615a8d565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001690550190556120aa565b6120a38161584f565b9050611f0c565b5073ffffffffffffffffffffffffffffffffffffffff83166000818152600c6020908152604080832067ffffffffffffffff89168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a250505050565b600080612151613f56565b826020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146121ba576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e08301516000908152600e602052604090205461222257600291508260e001517f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee18460200151868560405161221293929190615abc565b60405180910390a250600061252f565b600e60008460e001518152602001908152602001600020548360405160200161224b919061592a565b60405160208183030381529060405280519060200120146122a657600691508260e001517f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee18460200151868560405161221293929190615abc565b826101400151836080015163ffffffff166122c19190615aee565b64ffffffffff165a101561230f57600491508260e001517f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee18460200151868560405161221293929190615abc565b6000612324846080015163ffffffff16614184565b61232e9088615b0c565b90506000818786600001516123439190615b34565b61234d9190615b34565b606086015167ffffffffffffffff166000908152600b60205260409020549091506bffffffffffffffffffffffff90811690821611156123db57600593508460e001517f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee1866020015188876040516123c793929190615abc565b60405180910390a2506000915061252f9050565b8460a001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111561244357600393508460e001517f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee1866020015188876040516123c793929190615abc565b5050600e60008460e00151815260200190815260200160002060009055600061247b8460e001518a8a87608001518860400151614226565b805190915061248b57600161248e565b60005b925060006124bd85606001518660a00151876040015188600001518c6124b78860200151614184565b8d6143a2565b9050846060015167ffffffffffffffff168560e001517f47ffcaa55fde21cc7135c65541826c9e65dda59c29dc109aae964989e8fc664b83602001518988876000015161250a578e61250c565b8f5b8860400151604051612522959493929190615b59565b60405180910390a3519150505b965096945050505050565b6000612544613f56565b61254c614024565b600980546000906125669067ffffffffffffffff16615bbb565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c08101825260008082523360208301529181018290526060810182905291925060808201906040519080825280602002602001820160405280156125dc578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff84168152600b825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff938416178455938601516060870151909116909302921691909117600182015560808301518051919261267792600285019290910190614955565b5060a0919091015160039091015560405133815267ffffffffffffffff8216907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b600080600080606060006126da876135e2565b67ffffffffffffffff87166000908152600b602090815260409182902080546001820154600290920180548551818602810186019096528086526bffffffffffffffffffffffff8084169c5073ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009485900481169c509085169a50929093049091169650918301828280156127a657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161277b575b50505067ffffffffffffffff8a166000908152600b6020526040902060030154929450919250505091939550919395565b6127df613f56565b600a5473ffffffffffffffffffffffffffffffffffffffff163314612830576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020811461286a576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061287882840184614ace565b67ffffffffffffffff81166000908152600b60205260409020549091506c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff166128f1576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600b6020526040812080546bffffffffffffffffffffffff16918691906129288385615b34565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555084600960088282829054906101000a90046bffffffffffffffffffffffff1661297f9190615b34565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f88287846129e69190615680565b6040805192835260208301919091520160405180910390a2505050505050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff1680612a65576040517f80833e330000000000000000000000000000000000000000000000000000000081526004810184905260240161084a565b92915050565b612a736139bd565b60075461ffff808316911603612ab5576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000061ffff168161ffff161115612b17576040517fe9a3062200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160608101825260075461ffff90811680835290841660208301529091820190612b449043615680565b67ffffffffffffffff9081169091528151600880546020850151604090950151909316640100000000027fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff61ffff95861662010000027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009095169590931694909417929092171691909117905550565b612bdc6139bd565b60055467ffffffffffffffff16431015612c22576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b600354811015612d4557600060036000018281548110612c4757612c476155ae565b90600052602060002001549050600060036001018381548110612c6c57612c6c6155ae565b6000918252602080832091909101548483526002825260409283902054835186815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352169181018290529091507ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf949060600160405180910390a160009182526002602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055612d3e8161584f565b9050612c25565b5060036000612d5482826149cf565b612d626001830160006149cf565b5060020180547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000169055565b600554600380546040805160208084028201810190925282815267ffffffffffffffff9094169360609384939192909190830182828015612dee57602002820191906000526020600020905b815481526020019060010190808311612dda575b505050505091506003600101805480602002602001604051908101604052809291908181526020018280548015612e5b57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612e30575b50505050509050909192565b600f54601080546040805160208084028201810190925282815261ffff8516946bffffffffffffffffffffffff62010000820416946e01000000000000000000000000000090910460e01b93606093830182828015612f1157602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612ed45790505b5050505050905090919293565b612f26613f56565b612f2f82613f5e565b612f37614024565b612f4082613189565b15612f77576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61104e8282613658565b612f896135da565b600a546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612ff8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061301c91906158d5565b6009549091506801000000000000000090046bffffffffffffffffffffffff1681811115613080576040517fa99da302000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161084a565b818110156118e25760006130948284615a7a565b600a546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff87811660048301526024820184905292935091169063a9059cbb906044016020604051808303816000875af115801561310f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061313391906158b3565b506040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b67ffffffffffffffff81166000908152600b602090815260408083206002018054825181850281018501909352808352849383018282801561320157602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116131d6575b5050505050905060005b81518110156132ce576000600c600084848151811061322c5761322c6155ae565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff81161515825261010081048316948201859052690100000000000000000090049091169181018290529250146132bd57506001949350505050565b506132c78161584f565b905061320b565b5060009392505050565b6132e06139bd565b6040805160606020601f850181900402820181018352918101838152909182919085908590819085018382808284376000920191909152505050908252506007546020909101906133359061ffff1643615680565b67ffffffffffffffff16905260008052600660205280517f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f890819061337a90826156e1565b5060209190910151600190910180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9092169190911790556040517fdf3b58e133a3ba6c2ac90fe2b70fef7f7d69dd675fe9c542a6f0fe2f3a8a6f3a906133f290600090859085906157fb565b60405180910390a15050565b6134066139bd565b600081815260066020526040808220815180830190925280548290829061342c906155dd565b80601f0160208091040260200160405190810160405280929190818152602001828054613458906155dd565b80156134a55780601f1061347a576101008083540402835291602001916134a5565b820191906000526020600020905b81548152906001019060200180831161348857829003601f168201915b50505091835250506001919091015467ffffffffffffffff9081166020928301529082015191925016431015613507576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61351082612a06565b81516040517f8cc6acce00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9290921691638cc6acce9161356491600401614bac565b600060405180830381600087803b15801561357e57600080fd5b505af1158015613592573d6000803e3d6000fd5b505082516040517fd97d1d65f3cae3537cf4c61e688583d89aae53d8b32accdfe7cb189e65ef34c793506133f29250859190615630565b6135d16139bd565b6107eb816145eb565b610ee66139bd565b67ffffffffffffffff81166000908152600b60205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff166107eb576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600b60209081526040808320815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168488015260018501549182168487015291900416606082015260028201805484518187028101870190955280855291949293608086019390929083018282801561373957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161370e575b505050918352505060039190910154602090910152805190915060005b8260800151518110156137fa57600c60008460800151838151811061377d5761377d6155ae565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690556137f38161584f565b9050613756565b5067ffffffffffffffff84166000908152600b60205260408120818155600181018290559061382c60028301826149cf565b6003820160009055505080600960088282829054906101000a90046bffffffffffffffffffffffff1661385f9190615887565b82546101009290920a6bffffffffffffffffffffffff818102199093169183160217909155600a546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015292851660248201529116915063a9059cbb906044016020604051808303816000875af11580156138fe573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061392291906158b3565b613958576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd498159101612138565b600054610100900473ffffffffffffffffffffffffffffffffffffffff163314610ee6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161084a565b60008060008084806020019051810190613a5d9190615bf8565b6040805160808101825261ffff86168082526bffffffffffffffffffffffff861660208084018290527fffffffff0000000000000000000000000000000000000000000000000000000087169484019490945260608301859052600f80547fffffffffffffffffffffffffffffffffffff00000000000000000000000000001690921762010000909102177fffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff166e01000000000000000000000000000060e087901c021781558351969a509498509296509094509092613b4391601091908601906149ed565b509050507fe6a1eda76d42a6d1d813f26765716562044db1e8bd8be7d088705e64afd301ca838383604051613b7a93929190615cf3565b60405180910390a15050505050565b613b916146e6565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000613c10613f56565b613c19856135e2565b613c233386614752565b613c2d85836107ee565b604080516101008101825233815267ffffffffffffffff87166000818152600b6020818152858320805473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009091048116838801528688018c90526060870186905261ffff8b1660808801529484529190526003015460a084015263ffffffff861660c0840152600f546201000090046bffffffffffffffffffffffff1660e084015292517fbdd7e8800000000000000000000000000000000000000000000000000000000081529089169163bdd7e88091613d0d9190600401615d4b565b610160604051808303816000875af1158015613d2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d519190615e36565b9050604051806101600160405280600f60000160029054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018767ffffffffffffffff1681526020018463ffffffff1681526020018260a001516bffffffffffffffffffffffff1681526020018260c0015164ffffffffff1681526020018260e00151815260200182610100015169ffffffffffffffffffff16815260200182610120015164ffffffffff16815260200182610140015164ffffffffff16815250604051602001613e60919061592a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060e08401516000908152600e90935291205560a0810151613eba90339088906147c6565b60e081015167ffffffffffffffff87166000818152600b60205260409081902054905191928b9290917f7c720ccd20069b8311a6be4ba1cf3294d09eb247aa5d73a8502054b6e68a2f5491613f3f916c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1690339032908d908d908d90615f09565b60405180910390a460e00151979650505050505050565b610ee66148a1565b67ffffffffffffffff81166000908152600b60205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1680613fd5576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff82161461104e576040517f5a68151d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61404d7fd8e0666292c202b1ce6a8ff0dd638652e662402ac53fbf9bd9d3bcc39d5eb097612a06565b604080516000815260208101918290527f6b14daf80000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff9190911690636b14daf8906140b090339060248101615f6d565b602060405180830381865afa1580156140cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140f191906158b3565b610ee6576040517f2290626300000000000000000000000000000000000000000000000000000000815233600482015260240161084a565b6141316148a1565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258613bdc3390565b60006bffffffffffffffffffffffff821115614222576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f3620626974730000000000000000000000000000000000000000000000000000606482015260840161084a565b5090565b60408051606080820183526000808352602083015291810191909152600f546040516000916e010000000000000000000000000000900460e01b9061427390899089908990602401615f9c565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529181526020820180517fffffffff00000000000000000000000000000000000000000000000000000000949094167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909416939093179092528151608480825260c0820190935290925060009182918291602082018180368337019050509050853b61432557600080fd5b5a61138881101561433557600080fd5b61138881039050876040820482031161434d57600080fd5b60008086516020880160008b8df193505a900391503d6084811115614370575060845b808252806000602084013e50604080516060810182529315158452602084019290925290820152979650505050505050565b604080518082019091526000808252602082015260006143c28486615b0c565b90506000816143d18886615b34565b6143db9190615b34565b6040805180820182526bffffffffffffffffffffffff808616825280841660208084019190915267ffffffffffffffff8f166000908152600b90915292832080549297509394508493929161443291859116615887565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550818461446c9190615b34565b336000908152600d6020526040812080549091906144999084906bffffffffffffffffffffffff16615b34565b82546101009290920a6bffffffffffffffffffffffff818102199093169183160217909155306000908152600d6020526040812080548b945090926144e091859116615b34565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c166000908152600b6020526040812060010180548d9450909261453491859116615887565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff88166000908152600c6020908152604080832067ffffffffffffffff808f168552925290912080546001926009916145b89185916901000000000000000000900416615a59565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050979650505050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361466a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161084a565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929361010090910416917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005460ff16610ee6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161084a565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600c6020908152604080832067ffffffffffffffff8516845290915290205460ff1661104e576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600b6020526040812060010180548392906148009084906bffffffffffffffffffffffff16615b34565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff85166000908152600c6020908152604080832067ffffffffffffffff8089168552925290912080546001945090928492614876928492900416615a59565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b60005460ff1615610ee6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a2070617573656400000000000000000000000000000000604482015260640161084a565b828054828255906000526020600020908101928215614949579160200282015b8281111561494957825182559160200191906001019061492e565b50614222929150614a93565b828054828255906000526020600020908101928215614949579160200282015b8281111561494957825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614975565b50805460008255906000526020600020908101906107eb9190614a93565b828054828255906000526020600020906007016008900481019282156149495791602002820160005b83821115614a5a57835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302614a16565b8015614a8a5782816101000a81549063ffffffff0219169055600401602081600301049283019260010302614a5a565b50506142229291505b5b808211156142225760008155600101614a94565b67ffffffffffffffff811681146107eb57600080fd5b8035614ac981614aa8565b919050565b600060208284031215614ae057600080fd5b8135614aeb81614aa8565b9392505050565b63ffffffff811681146107eb57600080fd5b8035614ac981614af2565b60008060408385031215614b2257600080fd5b8235614b2d81614aa8565b91506020830135614b3d81614af2565b809150509250929050565b6000815180845260005b81811015614b6e57602081850181015186830182015201614b52565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000614aeb6020830184614b48565b60008060408385031215614bd257600080fd5b8235614bdd81614aa8565b946020939093013593505050565b60008083601f840112614bfd57600080fd5b50813567ffffffffffffffff811115614c1557600080fd5b602083019150836020828501011115614c2d57600080fd5b9250929050565b600080600060408486031215614c4957600080fd5b83359250602084013567ffffffffffffffff811115614c6757600080fd5b614c7386828701614beb565b9497909650939450505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715614cd357614cd3614c80565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614d2057614d20614c80565b604052919050565b600067ffffffffffffffff821115614d4257614d42614c80565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146107eb57600080fd5b8035614ac981614d4c565b600082601f830112614d8a57600080fd5b81356020614d9f614d9a83614d28565b614cd9565b82815260059290921b84018101918181019086841115614dbe57600080fd5b8286015b84811015614de2578035614dd581614d4c565b8352918301918301614dc2565b509695505050505050565b60008060408385031215614e0057600080fd5b823567ffffffffffffffff80821115614e1857600080fd5b818501915085601f830112614e2c57600080fd5b81356020614e3c614d9a83614d28565b82815260059290921b84018101918181019089841115614e5b57600080fd5b948201945b83861015614e7957853582529482019490820190614e60565b96505086013592505080821115614e8f57600080fd5b50614e9c85828601614d79565b9150509250929050565b61ffff811681146107eb57600080fd5b60008060008060008060a08789031215614ecf57600080fd5b8635614eda81614aa8565b9550602087013567ffffffffffffffff811115614ef657600080fd5b614f0289828a01614beb565b9096509450506040870135614f1681614ea6565b92506060870135614f2681614af2565b80925050608087013590509295509295509295565b60008060408385031215614f4e57600080fd5b8235614f5981614aa8565b91506020830135614b3d81614d4c565b6bffffffffffffffffffffffff811681146107eb57600080fd5b8035614ac981614f69565b60008060408385031215614fa157600080fd5b8235614fac81614d4c565b91506020830135614b3d81614f69565b60008060408385031215614fcf57600080fd5b8235614fda81614d4c565b91506020830135614b3d81614aa8565b600060208284031215614ffc57600080fd5b5035919050565b6000806020838503121561501657600080fd5b823567ffffffffffffffff8082111561502e57600080fd5b818501915085601f83011261504257600080fd5b81358181111561505157600080fd5b8660206101608302850101111561506757600080fd5b60209290920196919550909350505050565b600082601f83011261508a57600080fd5b813567ffffffffffffffff8111156150a4576150a4614c80565b6150d560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614cd9565b8181528460208386010111156150ea57600080fd5b816020850160208301376000918101602001919091529392505050565b64ffffffffff811681146107eb57600080fd5b8035614ac981615107565b69ffffffffffffffffffff811681146107eb57600080fd5b8035614ac981615125565b6000610160828403121561515b57600080fd5b615163614caf565b905061516e82614f83565b815261517c60208301614d6e565b602082015261518d60408301614d6e565b604082015261519e60608301614abe565b60608201526151af60808301614b04565b60808201526151c060a08301614f83565b60a08201526151d160c0830161511a565b60c082015260e082013560e08201526101006151ee81840161513d565b9082015261012061520083820161511a565b9082015261014061521283820161511a565b9082015292915050565b600080600080600080610200878903121561523657600080fd5b863567ffffffffffffffff8082111561524e57600080fd5b61525a8a838b01615079565b9750602089013591508082111561527057600080fd5b5061527d89828a01615079565b955050604087013561528e81614f69565b9350606087013561529e81614f69565b925060808701356152ae81614d4c565b91506152bd8860a08901615148565b90509295509295509295565b60078110615300577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6040810161531282856152c9565b6bffffffffffffffffffffffff831660208301529392505050565b600081518084526020808501945080840160005b8381101561537357815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101615341565b509495945050505050565b60006bffffffffffffffffffffffff808916835273ffffffffffffffffffffffffffffffffffffffff808916602085015281881660408501528087166060850152505060c060808301526153d560c083018561532d565b90508260a0830152979650505050505050565b600080600080606085870312156153fe57600080fd5b843561540981614d4c565b935060208501359250604085013567ffffffffffffffff81111561542c57600080fd5b61543887828801614beb565b95989497509550505050565b60006020828403121561545657600080fd5b8135614aeb81614ea6565b6000606082018583526020606081850152818651808452608086019150828801935060005b818110156154a257845183529383019391830191600101615486565b50508481036040860152610f3c818761532d565b600081518084526020808501945080840160005b8381101561537357815163ffffffff16875295820195908201906001016154ca565b61ffff851681526bffffffffffffffffffffffff841660208201527fffffffff000000000000000000000000000000000000000000000000000000008316604082015260806060820152600061554560808301846154b6565b9695505050505050565b60006020828403121561556157600080fd5b8135614aeb81614d4c565b6000806020838503121561557f57600080fd5b823567ffffffffffffffff81111561559657600080fd5b6155a285828601614beb565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c908216806155f157607f821691505b60208210810361562a577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b8281526040602082015260006156496040830184614b48565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115612a6557612a65615651565b601f8211156118e257600081815260208120601f850160051c810160208610156156ba5750805b601f850160051c820191505b818110156156d9578281556001016156c6565b505050505050565b815167ffffffffffffffff8111156156fb576156fb614c80565b61570f8161570984546155dd565b84615693565b602080601f831160018114615762576000841561572c5750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556156d9565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156157af57888601518255948401946001909101908401615790565b50858210156157eb57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361588057615880615651565b5060010190565b6bffffffffffffffffffffffff8281168282160390808211156158ac576158ac615651565b5092915050565b6000602082840312156158c557600080fd5b81518015158114614aeb57600080fd5b6000602082840312156158e757600080fd5b5051919050565b600060ff821660ff810361590457615904615651565b60010192915050565b6000610160828403121561592057600080fd5b614aeb8383615148565b81516bffffffffffffffffffffffff16815261016081016020830151615968602084018273ffffffffffffffffffffffffffffffffffffffff169052565b506040830151615990604084018273ffffffffffffffffffffffffffffffffffffffff169052565b5060608301516159ac606084018267ffffffffffffffff169052565b5060808301516159c4608084018263ffffffff169052565b5060a08301516159e460a08401826bffffffffffffffffffffffff169052565b5060c08301516159fd60c084018264ffffffffff169052565b5060e083015160e083015261010080840151615a268285018269ffffffffffffffffffff169052565b50506101208381015164ffffffffff81168483015250506101408381015164ffffffffff8116848301525b505092915050565b67ffffffffffffffff8181168382160190808211156158ac576158ac615651565b81810381811115612a6557612a65615651565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8481168252831660208201526060810161564960408301846152c9565b64ffffffffff8181168382160190808211156158ac576158ac615651565b6bffffffffffffffffffffffff818116838216028082169190828114615a5157615a51615651565b6bffffffffffffffffffffffff8181168382160190808211156158ac576158ac615651565b6bffffffffffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152615b9360408201856152c9565b60a060608201526000615ba960a0830185614b48565b8281036080840152610f3c8185614b48565b600067ffffffffffffffff808316818103615bd857615bd8615651565b6001019392505050565b8051614ac981614f69565b8051614ac981614af2565b60008060008060808587031215615c0e57600080fd5b8451615c1981614ea6565b80945050602080860151615c2c81614f69565b60408701519094507fffffffff0000000000000000000000000000000000000000000000000000000081168114615c6257600080fd5b606087015190935067ffffffffffffffff811115615c7f57600080fd5b8601601f81018813615c9057600080fd5b8051615c9e614d9a82614d28565b81815260059190911b8201830190838101908a831115615cbd57600080fd5b928401925b82841015615ce4578351615cd581614af2565b82529284019290840190615cc2565b979a9699509497505050505050565b6bffffffffffffffffffffffff841681527fffffffff0000000000000000000000000000000000000000000000000000000083166020820152606060408201526000615d4260608301846154b6565b95945050505050565b60208152600073ffffffffffffffffffffffffffffffffffffffff808451166020840152806020850151166040840152506040830151610100806060850152615d98610120850183614b48565b91506060850151615db5608086018267ffffffffffffffff169052565b50608085015161ffff811660a08601525060a085015160c085015260c0850151615de760e086018263ffffffff169052565b5060e08501516bffffffffffffffffffffffff8116858301525090949350505050565b8051614ac981614d4c565b8051614ac981614aa8565b8051614ac981615107565b8051614ac981615125565b60006101608284031215615e4957600080fd5b615e51614caf565b615e5a83615be2565b8152615e6860208401615e0a565b6020820152615e7960408401615e0a565b6040820152615e8a60608401615e15565b6060820152615e9b60808401615bed565b6080820152615eac60a08401615be2565b60a0820152615ebd60c08401615e20565b60c082015260e083015160e0820152610100615eda818501615e2b565b90820152610120615eec848201615e20565b90820152610140615efe848201615e20565b908201529392505050565b600073ffffffffffffffffffffffffffffffffffffffff8089168352808816602084015280871660408401525060c06060830152615f4a60c0830186614b48565b905061ffff8416608083015263ffffffff831660a0830152979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006156496040830184614b48565b838152606060208201526000615fb56060830185614b48565b82810360408401526155458185614b4856fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"timelockBlocks\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"maximumTimelockBlocks\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structIFunctionsRouter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ConsumerRequestsInFlight\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"limit\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"IdentifierIsReserved\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"value\",\"type\":\"uint8\"}],\"name\":\"InvalidGasFlagValue\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProposal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeProposedOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeSubscriptionOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByRoute\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ProposedTimelockAboveMaximum\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"RouteNotFound\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"SafeERC20FailedOperation\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderMustAcceptTermsOfService\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TimelockInEffect\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"indexed\":false,\"internalType\":\"structIFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ConfigChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"toBytes\",\"type\":\"bytes\"}],\"name\":\"ConfigProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"toBytes\",\"type\":\"bytes\"}],\"name\":\"ConfigUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"proposedContractSetId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetFromAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"proposedContractSetToAddress\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"timelockEndBlock\",\"type\":\"uint64\"}],\"name\":\"ContractProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"ContractUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"}],\"name\":\"RequestNotProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"totalCostJuels\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"RequestProcessed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"subscriptionOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestingContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"requestInitiator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"}],\"name\":\"RequestStart\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"}],\"name\":\"RequestTimedOut\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"fundsRecipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsAmount\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"from\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"to\",\"type\":\"uint16\"}],\"name\":\"TimeLockProposed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"from\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"to\",\"type\":\"uint16\"}],\"name\":\"TimeLockUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MAX_CALLBACK_RETURN_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"err\",\"type\":\"bytes\"},{\"internalType\":\"uint96\",\"name\":\"juelsPerGas\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"costWithoutCallback\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"transmitter\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"uint40\",\"name\":\"timeoutTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint80\",\"name\":\"donFee\",\"type\":\"uint80\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"}],\"internalType\":\"structFunctionsResponse.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"}],\"name\":\"fulfill\",\"outputs\":[{\"internalType\":\"enumFunctionsResponse.FulfillResult\",\"name\":\"resultCode\",\"type\":\"uint8\"},{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListId\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"maxConsumersPerSubscription\",\"type\":\"uint16\"},{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"bytes4\",\"name\":\"handleOracleFulfillmentSelector\",\"type\":\"bytes4\"},{\"internalType\":\"uint32[]\",\"name\":\"maxCallbackGasLimits\",\"type\":\"uint32[]\"}],\"internalType\":\"structIFunctionsRouter.Config\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getConsumer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"initiatedRequests\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"completedRequests\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getFlags\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"getProposedContractById\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getProposedContractSet\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timelockEndBlock\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"ids\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"to\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"blockedBalance\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"internalType\":\"structIFunctionsSubscriptions.Subscription\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSubscriptionCount\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"isValidCallbackGasLimit\",\"outputs\":[],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"oracleWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"ownerWithdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"proposeConfigUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"config\",\"type\":\"bytes\"}],\"name\":\"proposeConfigUpdateSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"proposedContractSetIds\",\"type\":\"bytes32[]\"},{\"internalType\":\"address[]\",\"name\":\"proposedContractSetAddresses\",\"type\":\"address[]\"}],\"name\":\"proposeContractsUpdate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"proposeSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequest\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"internalType\":\"uint16\",\"name\":\"dataVersion\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"donId\",\"type\":\"bytes32\"}],\"name\":\"sendRequestToProposed\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"flags\",\"type\":\"bytes32\"}],\"name\":\"setFlags\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint96\",\"name\":\"adminFee\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"client\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"subscriptionId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint96\",\"name\":\"estimatedTotalCostJuels\",\"type\":\"uint96\"},{\"internalType\":\"uint40\",\"name\":\"timeoutTimestamp\",\"type\":\"uint40\"},{\"internalType\":\"bytes32\",\"name\":\"requestId\",\"type\":\"bytes32\"},{\"internalType\":\"uint80\",\"name\":\"donFee\",\"type\":\"uint80\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadBeforeCallback\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"gasOverheadAfterCallback\",\"type\":\"uint40\"}],\"internalType\":\"structFunctionsResponse.Commitment[]\",\"name\":\"requestsToTimeoutByCommitment\",\"type\":\"tuple[]\"}],\"name\":\"timeoutRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"name\":\"updateConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateConfigSelf\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"updateContracts\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60c06040523480156200001157600080fd5b506040516200651c3803806200651c8339810160408190526200003491620004a3565b6001600160a01b0382166080526006805460ff191690553380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600680546001600160a01b0380851661010002610100600160a81b031990921691909117909155811615620000dc57620000dc816200014b565b5050600b805461ffff80881661ffff1990921691909117909155841660a052506000805260086020527f5eff886ea0ce6ca488a3d6e336d6c0f75f46d19b42c06ce5ee98e42c96d256c780546001600160a01b031916301790556200014181620001fd565b5050505062000641565b336001600160a01b03821603620001a55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600780546001600160a01b0319166001600160a01b03838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b805160098054602080850151604086015160e01c600160701b0263ffffffff60701b196001600160601b0390921662010000026001600160701b031990941661ffff9096169590951792909217919091169290921781556060830151805184936200026e92600a92910190620002ae565b509050507f9988860843c5f26e38bf5b1c43b17689b36487e4beb67dbc84264cc5bf41786081604051620002a39190620005b2565b60405180910390a150565b82805482825590600052602060002090600701600890048101928215620003525791602002820160005b838211156200031e57835183826101000a81548163ffffffff021916908363ffffffff1602179055509260200192600401602081600301049283019260010302620002d8565b8015620003505782816101000a81549063ffffffff02191690556004016020816003010492830192600103026200031e565b505b506200036092915062000364565b5090565b5b8082111562000360576000815560010162000365565b805161ffff811681146200038e57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715620003ce57620003ce62000393565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620003ff57620003ff62000393565b604052919050565b600082601f8301126200041957600080fd5b815160206001600160401b0382111562000437576200043762000393565b8160051b62000448828201620003d4565b92835284810182019282810190878511156200046357600080fd5b83870192505b848310156200049857825163ffffffff81168114620004885760008081fd5b8252918301919083019062000469565b979650505050505050565b60008060008060808587031215620004ba57600080fd5b620004c5856200037b565b9350620004d5602086016200037b565b60408601519093506001600160a01b0381168114620004f357600080fd5b60608601519092506001600160401b03808211156200051157600080fd5b90860190608082890312156200052657600080fd5b62000530620003a9565b6200053b836200037b565b815260208301516001600160601b03811681146200055857600080fd5b602082015260408301516001600160e01b0319811681146200057957600080fd5b60408201526060830151828111156200059157600080fd5b6200059f8a82860162000407565b6060830152509598949750929550505050565b6020808252825161ffff1682820152828101516001600160601b03166040808401919091528301516001600160e01b031916606080840191909152830151608080840152805160a0840181905260009291820190839060c08601905b808310156200063657835163ffffffff1682529284019260019290920191908401906200060e565b509695505050505050565b60805160a051615e9c620006806000396000505060008181611174015281816124f101528181612bc801528181612cd0015261345e0152615e9c6000f3fe608060405234801561001057600080fd5b50600436106102de5760003560e01c80637341c10c11610186578063a9c9a918116100e3578063d7ae1d3011610097578063ea5d840f11610071578063ea5d840f14610704578063eb523d6c14610717578063f2fde38b1461072a57600080fd5b8063d7ae1d30146106cb578063e72f6e30146106de578063e82ad7d4146106f157600080fd5b8063b734c0f4116100c8578063b734c0f414610697578063badc3eb61461069f578063c3f909d4146106b657600080fd5b8063a9c9a9181461065e578063aab396bd1461067157600080fd5b80639f87fad71161013a578063a21a23e41161011f578063a21a23e414610623578063a47c76961461062b578063a4c0ed361461064b57600080fd5b80639f87fad7146105ef578063a1d4c8281461060257600080fd5b8063823597401161016b57806382359740146105b15780638456cb59146105c45780638da5cb5b146105cc57600080fd5b80637341c10c1461059657806379ba5097146105a957600080fd5b806341db4ca31161023f5780635ed6dfba116101f3578063674603d0116101cd578063674603d0146104b65780636a2215de1461054b5780636e3b33231461058357600080fd5b80635ed6dfba1461046957806366316d8d1461047c578063664199701461048f57600080fd5b80634b8832d3116102245780634b8832d31461041157806355fedefa146104245780635c975abb1461045257600080fd5b806341db4ca3146103dd578063461d2762146103fe57600080fd5b80631c02453911610296578063385de9ae1161027b578063385de9ae146103af5780633e871e4d146103c25780633f4ba83a146103d557600080fd5b80631c024539146103945780631ded3b361461039c57600080fd5b806310fc49c1116102c757806310fc49c11461031857806312b583491461032b578063181f5a771461034b57600080fd5b806302bcc5b6146102e35780630c5d49cb146102f8575b600080fd5b6102f66102f1366004614960565b61073d565b005b610300608481565b60405161ffff90911681526020015b60405180910390f35b6102f661032636600461499a565b61079c565b6000546040516bffffffffffffffffffffffff909116815260200161030f565b6103876040518060400160405280601781526020017f46756e6374696f6e7320526f757465722076312e302e3000000000000000000081525081565b60405161030f9190614a41565b6102f6610898565b6102f66103aa366004614a54565b610a1e565b6102f66103bd366004614ac9565b610a50565b6102f66103d0366004614ca5565b610b59565b6102f6610e9a565b6103f06103eb366004614d6e565b610eac565b60405190815260200161030f565b6103f061040c366004614d6e565b610f0c565b6102f661041f366004614df3565b610f18565b6103f0610432366004614960565b67ffffffffffffffff166000908152600360208190526040909120015490565b60065460ff165b604051901515815260200161030f565b6102f6610477366004614e46565b611016565b6102f661048a366004614e46565b6111b8565b60025467ffffffffffffffff165b60405167ffffffffffffffff909116815260200161030f565b6105236104c4366004614e74565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815260046020908152604080832067ffffffffffffffff948516845290915290205460ff8116926101008204831692690100000000000000000090920490911690565b60408051931515845267ffffffffffffffff928316602085015291169082015260600161030f565b61055e610559366004614ea2565b61128f565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030f565b6102f6610591366004614ebb565b61134e565b6102f66105a4366004614df3565b61162a565b6102f66117c0565b6102f66105bf366004614960565b6118e7565b6102f6611a36565b600654610100900473ffffffffffffffffffffffffffffffffffffffff1661055e565b6102f66105fd366004614df3565b611a46565b6106156106103660046150d4565b611e1b565b60405161030f9291906151bc565b61049d61220f565b61063e610639366004614960565b61239c565b60405161030f9190615236565b6102f66106593660046152be565b6124d1565b61055e61066c366004614ea2565b61271d565b7fd8e0666292c202b1ce6a8ff0dd638652e662402ac53fbf9bd9d3bcc39d5eb0976103f0565b6102f6612782565b6106a761293c565b60405161030f9392919061531a565b6106be612a15565b60405161030f919061536f565b6102f66106d9366004614df3565b612b2c565b6102f66106ec36600461540e565b612b8f565b6104596106ff366004614960565b612d4c565b6102f661071236600461542b565b612e9b565b6102f6610725366004614ea2565b612fc1565b6102f661073836600461540e565b61318c565b61074561319d565b61074e816131a5565b67ffffffffffffffff81166000908152600360205260409020546107999082906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1661321b565b50565b67ffffffffffffffff8216600090815260036020819052604082200154600a54911a908110610801576040517f45c108ce00000000000000000000000000000000000000000000000000000000815260ff821660048201526024015b60405180910390fd5b600060096001018260ff168154811061081c5761081c61546d565b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1690508063ffffffff168363ffffffff161115610892576040517f1d70f87a00000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016107f8565b50505050565b6108a0613507565b60008080526010602052604080518082019091527f6e0956cda88cad152e89927e53611735b61a5c762d1428573c6931b0a5efcb018054829082906108e49061549c565b80601f01602080910402602001604051908101604052809291908181526020018280546109109061549c565b801561095d5780601f106109325761010080835404028352916020019161095d565b820191906000526020600020905b81548152906001019060200180831161094057829003601f168201915b50505091835250506001919091015467ffffffffffffffff90811660209283015290820151919250164310156109bf576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109df81600001518060200190518101906109da9190615505565b61358d565b80516040517fd97d1d65f3cae3537cf4c61e688583d89aae53d8b32accdfe7cb189e65ef34c791610a13916000919061562f565b60405180910390a150565b610a2661319d565b610a2f826131a5565b67ffffffffffffffff90911660009081526003602081905260409091200155565b610a58613507565b6040805160606020601f85018190040282018101835291810183815290918291908590859081908501838280828437600092019190915250505090825250600b54602090910190610aad9061ffff1643615677565b67ffffffffffffffff169052600084815260106020526040902081518190610ad590826156d8565b5060209190910151600190910180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9092169190911790556040517fdf3b58e133a3ba6c2ac90fe2b70fef7f7d69dd675fe9c542a6f0fe2f3a8a6f3a90610b4c908590859085906157f2565b60405180910390a1505050565b610b61613507565b8151815181141580610b735750600881115b15610baa576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b81811015610cd6576000848281518110610bc957610bc961546d565b602002602001015190506000848381518110610be757610be761546d565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161480610c52575060008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff8281169116145b15610c89576040517fee03280800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81610cc3576040517f4855c288000000000000000000000000000000000000000000000000000000008152600481018390526024016107f8565b505080610ccf90615846565b9050610bad565b50600b54600090610ceb9061ffff1643615677565b60408051606081018252868152602080820187905267ffffffffffffffff841692820192909252865192935091600d91610d299183918901906147a0565b506020828101518051610d4292600185019201906147e7565b5060409190910151600290910180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff90921691909117905560005b8451811015610e93577fbb4a5564503edfa78c35ff85fcc767ab37e97bd74f243e78b582b292671c004e858281518110610dc457610dc461546d565b602002602001015160086000888581518110610de257610de261546d565b6020026020010151815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16868481518110610e2b57610e2b61546d565b602002602001015185604051610e7b949392919093845273ffffffffffffffffffffffffffffffffffffffff92831660208501529116604083015267ffffffffffffffff16606082015260800190565b60405180910390a1610e8c81615846565b9050610d88565b5050505050565b610ea2613507565b610eaa61366f565b565b600080610eb88361128f565b9050610f0083828a8a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92508b91506136ec9050565b98975050505050505050565b600080610eb88361271d565b610f20613a41565b610f2982613a49565b610f31613b0f565b67ffffffffffffffff821660009081526003602052604090206001015473ffffffffffffffffffffffffffffffffffffffff8281166c0100000000000000000000000090920416146110125767ffffffffffffffff821660008181526003602090815260409182902060010180546bffffffffffffffffffffffff166c0100000000000000000000000073ffffffffffffffffffffffffffffffffffffffff8716908102919091179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be91015b60405180910390a25b5050565b61101e61319d565b806bffffffffffffffffffffffff166000036110545750306000908152600160205260409020546bffffffffffffffffffffffff165b306000908152600160205260409020546bffffffffffffffffffffffff808316911610156110ae576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b30600090815260016020526040812080548392906110db9084906bffffffffffffffffffffffff1661587e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550806000808282829054906101000a90046bffffffffffffffffffffffff16611131919061587e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061101282826bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613c529092919063ffffffff16565b6111c0613a41565b806bffffffffffffffffffffffff16600003611208576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600160205260409020546bffffffffffffffffffffffff80831691161015611262576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260016020526040812080548392906110db9084906bffffffffffffffffffffffff1661587e565b6000805b600d5460ff8216101561131857600d805460ff83169081106112b7576112b761546d565b9060005260206000200154830361130857600e805460ff83169081106112df576112df61546d565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169392505050565b611311816158aa565b9050611293565b506040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018390526024016107f8565b611356613a41565b60005b818110156116255760008383838181106113755761137561546d565b9050610160020180360381019061138c91906158c9565b905060008160e0015190506000826060015190506005600083815260200190815260200160002054836040516020016113c591906158e6565b6040516020818303038152906040528051906020012014611412576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260c0015164ffffffffff16421015611457576040517fbcc4005500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208301516040517f85b214cf0000000000000000000000000000000000000000000000000000000081526004810184905273ffffffffffffffffffffffffffffffffffffffff909116906385b214cf906024016020604051808303816000875af11580156114ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ee9190615a15565b5060a083015167ffffffffffffffff82166000908152600360205260408120600101805490919061152e9084906bffffffffffffffffffffffff1661587e565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555060408084015173ffffffffffffffffffffffffffffffffffffffff1660009081526004602090815282822067ffffffffffffffff8086168452915291902080546001926009916115b59185916901000000000000000000900416615a37565b825467ffffffffffffffff9182166101009390930a9283029190920219909116179055506000828152600560205260408082208290555183917ff1ca1e9147be737b04a2b018a79405f687a97de8dd8a2559bbe62357343af41491a25050508061161e90615846565b9050611359565b505050565b611632613a41565b61163b82613a49565b611643613b0f565b60095467ffffffffffffffff831660009081526003602052604090206002015461ffff90911690036116a1576040517f05a48e0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832067ffffffffffffffff8616845290915290205460ff16156116e8575050565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260046020908152604080832067ffffffffffffffff871680855290835281842080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155600384528285206002018054918201815585529383902090930180547fffffffffffffffffffffffff000000000000000000000000000000000000000016851790555192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e09101611009565b60075473ffffffffffffffffffffffffffffffffffffffff163314611841576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107f8565b600680547fffffffffffffffffffffff0000000000000000000000000000000000000000ff81166101003381810292909217909355600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040519290910473ffffffffffffffffffffffffffffffffffffffff169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6118ef613a41565b6118f7613b0f565b67ffffffffffffffff81166000908152600360205260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481169290910416338114611997576040517f4e1d9f1800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016107f8565b67ffffffffffffffff831660008181526003602090815260409182902080546c01000000000000000000000000339081026bffffffffffffffffffffffff928316178355600190920180549091169055825173ffffffffffffffffffffffffffffffffffffffff87168152918201527f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0910160405180910390a2505050565b611a3e613507565b610eaa613cdf565b611a4e613a41565b611a5782613a49565b611a5f613b0f565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260046020908152604080832067ffffffffffffffff8087168552908352928190208151606081018352905460ff8116151580835261010082048616948301949094526901000000000000000000900490931690830152611b07576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806040015167ffffffffffffffff16816020015167ffffffffffffffff1614611b5c576040517fbcc4005500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8316600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611bd757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611bac575b5050505050905060005b8151811015611d7f578373ffffffffffffffffffffffffffffffffffffffff16828281518110611c1357611c1361546d565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603611d6f578160018351611c459190615a58565b81518110611c5557611c5561546d565b6020026020010151600360008767ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018281548110611c9857611c9861546d565b600091825260208083209190910180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff949094169390931790925567ffffffffffffffff87168152600390915260409020600201805480611d1257611d12615a6b565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055019055611d7f565b611d7881615846565b9050611be1565b5073ffffffffffffffffffffffffffffffffffffffff8316600081815260046020908152604080832067ffffffffffffffff89168085529083529281902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a250505050565b600080611e26613a41565b826020015173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e8f576040517f8bec23e700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60e0830151600090815260056020526040902054611ef757600291508260e001517f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee184602001518685604051611ee793929190615a9a565b60405180910390a2506000612204565b600560008460e0015181526020019081526020016000205483604051602001611f2091906158e6565b6040516020818303038152906040528051906020012014611f7b57600691508260e001517f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee184602001518685604051611ee793929190615a9a565b826101400151836080015163ffffffff16611f969190615acc565b64ffffffffff165a1015611fe457600491508260e001517f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee184602001518685604051611ee793929190615a9a565b6000611ff9846080015163ffffffff16613d3a565b6120039088615aea565b90506000818786600001516120189190615b12565b6120229190615b12565b606086015167ffffffffffffffff166000908152600360205260409020549091506bffffffffffffffffffffffff90811690821611156120b057600593508460e001517f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee18660200151888760405161209c93929190615a9a565b60405180910390a250600091506122049050565b8460a001516bffffffffffffffffffffffff16816bffffffffffffffffffffffff16111561211857600393508460e001517f1a90e9a50793db2e394cf581e7c522e10c358a81e70acf6b5a0edd620c08dee18660200151888760405161209c93929190615a9a565b5050600560008460e0015181526020019081526020016000206000905560006121508460e001518a8a87608001518860400151613ddc565b8051909150612160576001612163565b60005b9250600061219285606001518660a00151876040015188600001518c61218c8860200151613d3a565b8d613f58565b9050846060015167ffffffffffffffff168560e001517f47ffcaa55fde21cc7135c65541826c9e65dda59c29dc109aae964989e8fc664b8360200151898887600001516121df578e6121e1565b8f5b88604001516040516121f7959493929190615b37565b60405180910390a3519150505b965096945050505050565b6000612219613a41565b612221613b0f565b6002805460009061223b9067ffffffffffffffff16615b99565b825467ffffffffffffffff8083166101009490940a93840293021916919091179091556040805160c08101825260008082523360208301529181018290526060810182905291925060808201906040519080825280602002602001820160405280156122b1578160200160208202803683370190505b5081526000602091820181905267ffffffffffffffff841681526003825260409081902083518484015173ffffffffffffffffffffffffffffffffffffffff9081166c010000000000000000000000009081026bffffffffffffffffffffffff938416178455938601516060870151909116909302921691909117600182015560808301518051919261234c926002850192909101906147e7565b5060a0919091015160039091015560405133815267ffffffffffffffff8216907f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a290565b6040805160c0810182526000808252602082018190529181018290526060808201839052608082015260a08101919091526123d6826131a5565b67ffffffffffffffff8216600090815260036020908152604091829020825160c08101845281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009283900481168487015260018501549182168488015291900416606082015260028201805485518186028101860190965280865291949293608086019392908301828280156124b757602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161248c575b505050505081526020016003820154815250509050919050565b6124d9613a41565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614612548576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612582576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061259082840184614960565b67ffffffffffffffff81166000908152600360205260409020549091506c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16612609576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260036020526040812080546bffffffffffffffffffffffff16918691906126408385615b12565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550846000808282829054906101000a90046bffffffffffffffffffffffff166126969190615b12565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f88287846126fd9190615677565b6040805192835260208301919091520160405180910390a2505050505050565b60008181526008602052604081205473ffffffffffffffffffffffffffffffffffffffff168061277c576040517f80833e33000000000000000000000000000000000000000000000000000000008152600481018490526024016107f8565b92915050565b61278a613507565b600f5467ffffffffffffffff164310156127d0576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b600d548110156128f3576000600d60000182815481106127f5576127f561546d565b906000526020600020015490506000600d600101838154811061281a5761281a61546d565b6000918252602080832091909101548483526008825260409283902054835186815273ffffffffffffffffffffffffffffffffffffffff91821693810193909352169181018290529091507ff8a6175bca1ba37d682089187edc5e20a859989727f10ca6bd9a5bc0de8caf949060600160405180910390a160009182526008602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9092169190911790556128ec81615846565b90506127d3565b50600d60006129028282614861565b612910600183016000614861565b5060020180547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000169055565b600f54600d80546040805160208084028201810190925282815267ffffffffffffffff909416936060938493919290919083018282801561299c57602002820191906000526020600020905b815481526020019060010190808311612988575b50505050509150600d600101805480602002602001604051908101604052809291908181526020018280548015612a0957602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116129de575b50505050509050909192565b6040805160808101825260008082526020820181905291810191909152606080820152604080516080810182526009805461ffff811683526201000081046bffffffffffffffffffffffff166020808501919091526e01000000000000000000000000000090910460e01b7fffffffff000000000000000000000000000000000000000000000000000000001683850152600a805485518184028101840190965280865293949293606086019392830182828015612b1e57602002820191906000526020600020906000905b82829054906101000a900463ffffffff1663ffffffff1681526020019060040190602082600301049283019260010382029150808411612ae15790505b505050505081525050905090565b612b34613a41565b612b3d82613a49565b612b45613b0f565b612b4e82612d4c565b15612b85576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611012828261321b565b612b9761319d565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015612c24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c489190615bc0565b6000549091506bffffffffffffffffffffffff1681811115612ca0576040517fa99da30200000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016107f8565b81811015611625576000612cb48284615a58565b9050612cf773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168583613c52565b6040805173ffffffffffffffffffffffffffffffffffffffff86168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b67ffffffffffffffff8116600090815260036020908152604080832060020180548251818502810185019093528083528493830182828015612dc457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612d99575b5050505050905060005b8151811015612e9157600060046000848481518110612def57612def61546d565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff808a168352908452908290208251606081018452905460ff8116151582526101008104831694820185905269010000000000000000009004909116918101829052925014612e8057506001949350505050565b50612e8a81615846565b9050612dce565b5060009392505050565b612ea3613507565b6040805160606020601f85018190040282018101835291810183815290918291908590859081908501838280828437600092019190915250505090825250600b54602090910190612ef89061ffff1643615677565b67ffffffffffffffff16905260008052601060205280517f6e0956cda88cad152e89927e53611735b61a5c762d1428573c6931b0a5efcb01908190612f3d90826156d8565b5060209190910151600190910180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9092169190911790556040517fdf3b58e133a3ba6c2ac90fe2b70fef7f7d69dd675fe9c542a6f0fe2f3a8a6f3a90612fb590600090859085906157f2565b60405180910390a15050565b612fc9613507565b6000818152601060205260408082208151808301909252805482908290612fef9061549c565b80601f016020809104026020016040519081016040528092919081815260200182805461301b9061549c565b80156130685780601f1061303d57610100808354040283529160200191613068565b820191906000526020600020905b81548152906001019060200180831161304b57829003601f168201915b50505091835250506001919091015467ffffffffffffffff90811660209283015290820151919250164310156130ca576040517fa93d035c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6130d38261271d565b81516040517f8cc6acce00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9290921691638cc6acce9161312791600401614a41565b600060405180830381600087803b15801561314157600080fd5b505af1158015613155573d6000803e3d6000fd5b505082516040517fd97d1d65f3cae3537cf4c61e688583d89aae53d8b32accdfe7cb189e65ef34c79350612fb5925085919061562f565b613194613507565b610799816141a1565b610eaa613507565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16610799576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160c08101835281546bffffffffffffffffffffffff808216835273ffffffffffffffffffffffffffffffffffffffff6c01000000000000000000000000928390048116848801526001850154918216848701529190041660608201526002820180548451818702810187019095528085529194929360808601939092908301828280156132fc57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116132d1575b505050918352505060039190910154602090910152805190915060005b8260800151518110156133bd5760046000846080015183815181106133405761334061546d565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff168252818101929092526040908101600090812067ffffffffffffffff89168252909252902080547fffffffffffffffffffffffffffffff00000000000000000000000000000000001690556133b681615846565b9050613319565b5067ffffffffffffffff8416600090815260036020526040812081815560018101829055906133ef6002830182614861565b5060006003919091018190558054829190819061341b9084906bffffffffffffffffffffffff1661587e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506134a283826bffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16613c529092919063ffffffff16565b6040805173ffffffffffffffffffffffffffffffffffffffff851681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8616917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd498159101611e0d565b600654610100900473ffffffffffffffffffffffffffffffffffffffff163314610eaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107f8565b805160098054602080850151604086015160e01c6e010000000000000000000000000000027fffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff6bffffffffffffffffffffffff90921662010000027fffffffffffffffffffffffffffffffffffff000000000000000000000000000090941661ffff90961695909517929092179190911692909217815560608301518051849361363c92600a9291019061487f565b509050507f9988860843c5f26e38bf5b1c43b17689b36487e4beb67dbc84264cc5bf41786081604051610a13919061536f565b61367761429d565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60006136f6613a41565b6136ff856131a5565b6137093386614309565b613713858361079c565b604080516101008101825233815267ffffffffffffffff8716600081815260036020818152858320805473ffffffffffffffffffffffffffffffffffffffff6c010000000000000000000000009091048116838801528688018c90526060870186905261ffff8b16608088015294845290829052015460a084015263ffffffff861660c08401526009546201000090046bffffffffffffffffffffffff1660e084015292517fbdd7e8800000000000000000000000000000000000000000000000000000000081529089169163bdd7e880916137f29190600401615bd9565b610160604051808303816000875af1158015613812573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138369190615cc4565b9050604051806101600160405280600960000160029054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1681526020013373ffffffffffffffffffffffffffffffffffffffff1681526020018767ffffffffffffffff1681526020018463ffffffff1681526020018260a001516bffffffffffffffffffffffff1681526020018260c0015164ffffffffff1681526020018260e00151815260200182610100015169ffffffffffffffffffff16815260200182610120015164ffffffffff16815260200182610140015164ffffffffff1681525060405160200161394591906158e6565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060e08401516000908152600590935291205560a081015161399f903390889061437d565b60e081015167ffffffffffffffff8716600081815260036020526040908190205460a0850151915192938c9390927ff67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec992613a2a926c0100000000000000000000000090910473ffffffffffffffffffffffffffffffffffffffff1691339132918e918e918e91615d97565b60405180910390a460e00151979650505050505050565b610eaa614458565b67ffffffffffffffff81166000908152600360205260409020546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1680613ac0576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff821614611012576040517f5a68151d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fd8e0666292c202b1ce6a8ff0dd638652e662402ac53fbf9bd9d3bcc39d5eb09760005260086020527f29d6d16866b6e23fcc7ae534ca080a7a6eca5e1882ac6bf4569628fa2ee46ea45473ffffffffffffffffffffffffffffffffffffffff1680613b785750565b604080516000815260208101918290527f6b14daf80000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff821690636b14daf890613bd990339060248101615e0f565b602060405180830381865afa158015613bf6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c1a9190615a15565b610799576040517f229062630000000000000000000000000000000000000000000000000000000081523360048201526024016107f8565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb000000000000000000000000000000000000000000000000000000001790526116259084906144c5565b613ce7614458565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586136c23390565b60006bffffffffffffffffffffffff821115613dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203960448201527f362062697473000000000000000000000000000000000000000000000000000060648201526084016107f8565b5090565b604080516060808201835260008083526020830152918101919091526009546040516000916e010000000000000000000000000000900460e01b90613e2990899089908990602401615e3e565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00181529181526020820180517fffffffff00000000000000000000000000000000000000000000000000000000949094167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff909416939093179092528151608480825260c0820190935290925060009182918291602082018180368337019050509050853b613edb57600080fd5b5a611388811015613eeb57600080fd5b611388810390508760408204820311613f0357600080fd5b60008086516020880160008b8df193505a900391503d6084811115613f26575060845b808252806000602084013e50604080516060810182529315158452602084019290925290820152979650505050505050565b60408051808201909152600080825260208201526000613f788486615aea565b9050600081613f878886615b12565b613f919190615b12565b6040805180820182526bffffffffffffffffffffffff808616825280841660208084019190915267ffffffffffffffff8f1660009081526003909152928320805492975093945084939291613fe89185911661587e565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915567ffffffffffffffff8c16600090815260036020526040812060010180548d9450909261403c9185911661587e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555081846140769190615b12565b33600090815260016020526040812080549091906140a39084906bffffffffffffffffffffffff16615b12565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915530600090815260016020526040812080548b945090926140ea91859116615b12565b82546bffffffffffffffffffffffff9182166101009390930a92830291909202199091161790555073ffffffffffffffffffffffffffffffffffffffff8816600090815260046020908152604080832067ffffffffffffffff808f1685529252909120805460019260099161416e9185916901000000000000000000900416615a37565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050979650505050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603614220576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107f8565b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600654604051919261010090910416907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b60065460ff16610eaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107f8565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260046020908152604080832067ffffffffffffffff8516845290915290205460ff16611012576040517f71e8313700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8216600090815260036020526040812060010180548392906143b79084906bffffffffffffffffffffffff16615b12565b82546bffffffffffffffffffffffff91821661010093840a908102920219161790915573ffffffffffffffffffffffffffffffffffffffff8516600090815260046020908152604080832067ffffffffffffffff808916855292529091208054600194509092849261442d928492900416615a37565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505050565b60065460ff1615610eaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107f8565b60006144e773ffffffffffffffffffffffffffffffffffffffff84168361455b565b9050805160001415801561450c57508080602001905181019061450a9190615a15565b155b15611625576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024016107f8565b606061459f838360006040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c656400008152506145a6565b9392505050565b606082471015614638576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016107f8565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516146619190615e73565b60006040518083038185875af1925050503d806000811461469e576040519150601f19603f3d011682016040523d82523d6000602084013e6146a3565b606091505b50915091506146b4878383876146c1565b925050505b949350505050565b606083156147575782516000036147505773ffffffffffffffffffffffffffffffffffffffff85163b614750576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107f8565b50816146b9565b6146b9838381511561476c5781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f89190614a41565b8280548282559060005260206000209081019282156147db579160200282015b828111156147db5782518255916020019190600101906147c0565b50613dd8929150614925565b8280548282559060005260206000209081019282156147db579160200282015b828111156147db57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614807565b50805460008255906000526020600020908101906107999190614925565b828054828255906000526020600020906007016008900481019282156147db5791602002820160005b838211156148ec57835183826101000a81548163ffffffff021916908363ffffffff16021790555092602001926004016020816003010492830192600103026148a8565b801561491c5782816101000a81549063ffffffff02191690556004016020816003010492830192600103026148ec565b5050613dd89291505b5b80821115613dd85760008155600101614926565b67ffffffffffffffff8116811461079957600080fd5b803561495b8161493a565b919050565b60006020828403121561497257600080fd5b813561459f8161493a565b63ffffffff8116811461079957600080fd5b803561495b8161497d565b600080604083850312156149ad57600080fd5b82356149b88161493a565b915060208301356149c88161497d565b809150509250929050565b60005b838110156149ee5781810151838201526020016149d6565b50506000910152565b60008151808452614a0f8160208601602086016149d3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061459f60208301846149f7565b60008060408385031215614a6757600080fd5b8235614a728161493a565b946020939093013593505050565b60008083601f840112614a9257600080fd5b50813567ffffffffffffffff811115614aaa57600080fd5b602083019150836020828501011115614ac257600080fd5b9250929050565b600080600060408486031215614ade57600080fd5b83359250602084013567ffffffffffffffff811115614afc57600080fd5b614b0886828701614a80565b9497909650939450505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610160810167ffffffffffffffff81118282101715614b6857614b68614b15565b60405290565b6040516080810167ffffffffffffffff81118282101715614b6857614b68614b15565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614bd857614bd8614b15565b604052919050565b600067ffffffffffffffff821115614bfa57614bfa614b15565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461079957600080fd5b803561495b81614c04565b600082601f830112614c4257600080fd5b81356020614c57614c5283614be0565b614b91565b82815260059290921b84018101918181019086841115614c7657600080fd5b8286015b84811015614c9a578035614c8d81614c04565b8352918301918301614c7a565b509695505050505050565b60008060408385031215614cb857600080fd5b823567ffffffffffffffff80821115614cd057600080fd5b818501915085601f830112614ce457600080fd5b81356020614cf4614c5283614be0565b82815260059290921b84018101918181019089841115614d1357600080fd5b948201945b83861015614d3157853582529482019490820190614d18565b96505086013592505080821115614d4757600080fd5b50614d5485828601614c31565b9150509250929050565b61ffff8116811461079957600080fd5b60008060008060008060a08789031215614d8757600080fd5b8635614d928161493a565b9550602087013567ffffffffffffffff811115614dae57600080fd5b614dba89828a01614a80565b9096509450506040870135614dce81614d5e565b92506060870135614dde8161497d565b80925050608087013590509295509295509295565b60008060408385031215614e0657600080fd5b8235614e118161493a565b915060208301356149c881614c04565b6bffffffffffffffffffffffff8116811461079957600080fd5b803561495b81614e21565b60008060408385031215614e5957600080fd5b8235614e6481614c04565b915060208301356149c881614e21565b60008060408385031215614e8757600080fd5b8235614e9281614c04565b915060208301356149c88161493a565b600060208284031215614eb457600080fd5b5035919050565b60008060208385031215614ece57600080fd5b823567ffffffffffffffff80821115614ee657600080fd5b818501915085601f830112614efa57600080fd5b813581811115614f0957600080fd5b86602061016083028501011115614f1f57600080fd5b60209290920196919550909350505050565b600082601f830112614f4257600080fd5b813567ffffffffffffffff811115614f5c57614f5c614b15565b614f8d60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614b91565b818152846020838601011115614fa257600080fd5b816020850160208301376000918101602001919091529392505050565b64ffffffffff8116811461079957600080fd5b803561495b81614fbf565b69ffffffffffffffffffff8116811461079957600080fd5b803561495b81614fdd565b6000610160828403121561501357600080fd5b61501b614b44565b905061502682614e3b565b815261503460208301614c26565b602082015261504560408301614c26565b604082015261505660608301614950565b60608201526150676080830161498f565b608082015261507860a08301614e3b565b60a082015261508960c08301614fd2565b60c082015260e082013560e08201526101006150a6818401614ff5565b908201526101206150b8838201614fd2565b908201526101406150ca838201614fd2565b9082015292915050565b60008060008060008061020087890312156150ee57600080fd5b863567ffffffffffffffff8082111561510657600080fd5b6151128a838b01614f31565b9750602089013591508082111561512857600080fd5b5061513589828a01614f31565b955050604087013561514681614e21565b9350606087013561515681614e21565b9250608087013561516681614c04565b91506151758860a08901615000565b90509295509295509295565b600781106151b8577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b604081016151ca8285615181565b6bffffffffffffffffffffffff831660208301529392505050565b600081518084526020808501945080840160005b8381101561522b57815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016151f9565b509495945050505050565b6020815260006bffffffffffffffffffffffff808451166020840152602084015173ffffffffffffffffffffffffffffffffffffffff8082166040860152826040870151166060860152806060870151166080860152505050608083015160c060a08401526152a860e08401826151e5565b905060a084015160c08401528091505092915050565b600080600080606085870312156152d457600080fd5b84356152df81614c04565b935060208501359250604085013567ffffffffffffffff81111561530257600080fd5b61530e87828801614a80565b95989497509550505050565b6000606082018583526020606081850152818651808452608086019150828801935060005b8181101561535b5784518352938301939183019160010161533f565b50508481036040860152610f0081876151e5565b6000602080835260a0830161ffff855116828501526bffffffffffffffffffffffff828601511660408501527fffffffff000000000000000000000000000000000000000000000000000000006040860151166060850152606085015160808086015281815180845260c0870191508483019350600092505b80831015614c9a57835163ffffffff1682529284019260019290920191908401906153e8565b60006020828403121561542057600080fd5b813561459f81614c04565b6000806020838503121561543e57600080fd5b823567ffffffffffffffff81111561545557600080fd5b61546185828601614a80565b90969095509350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600181811c908216806154b057607f821691505b6020821081036154e9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b805161495b81614e21565b805161495b8161497d565b6000602080838503121561551857600080fd5b825167ffffffffffffffff8082111561553057600080fd5b908401906080828703121561554457600080fd5b61554c614b6e565b825161555781614d5e565b81528284015161556681614e21565b8185015260408301517fffffffff000000000000000000000000000000000000000000000000000000008116811461559d57600080fd5b60408201526060830151828111156155b457600080fd5b80840193505086601f8401126155c957600080fd5b825191506155d9614c5283614be0565b82815260059290921b830184019184810190888411156155f857600080fd5b938501935b8385101561561f5784516156108161497d565b825293850193908501906155fd565b6060830152509695505050505050565b8281526040602082015260006146b960408301846149f7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561277c5761277c615648565b601f82111561162557600081815260208120601f850160051c810160208610156156b15750805b601f850160051c820191505b818110156156d0578281556001016156bd565b505050505050565b815167ffffffffffffffff8111156156f2576156f2614b15565b61570681615700845461549c565b8461568a565b602080601f83116001811461575957600084156157235750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b1785556156d0565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156157a657888601518255948401946001909101908401615787565b50858210156157e257878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b83815260406020820152816040820152818360608301376000818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361587757615877615648565b5060010190565b6bffffffffffffffffffffffff8281168282160390808211156158a3576158a3615648565b5092915050565b600060ff821660ff81036158c0576158c0615648565b60010192915050565b600061016082840312156158dc57600080fd5b61459f8383615000565b81516bffffffffffffffffffffffff16815261016081016020830151615924602084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604083015161594c604084018273ffffffffffffffffffffffffffffffffffffffff169052565b506060830151615968606084018267ffffffffffffffff169052565b506080830151615980608084018263ffffffff169052565b5060a08301516159a060a08401826bffffffffffffffffffffffff169052565b5060c08301516159b960c084018264ffffffffff169052565b5060e083015160e0830152610100808401516159e28285018269ffffffffffffffffffff169052565b50506101208381015164ffffffffff81168483015250506101408381015164ffffffffff8116848301525b505092915050565b600060208284031215615a2757600080fd5b8151801515811461459f57600080fd5b67ffffffffffffffff8181168382160190808211156158a3576158a3615648565b8181038181111561277c5761277c615648565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff848116825283166020820152606081016146b96040830184615181565b64ffffffffff8181168382160190808211156158a3576158a3615648565b6bffffffffffffffffffffffff818116838216028082169190828114615a0d57615a0d615648565b6bffffffffffffffffffffffff8181168382160190808211156158a3576158a3615648565b6bffffffffffffffffffffffff8616815273ffffffffffffffffffffffffffffffffffffffff85166020820152615b716040820185615181565b60a060608201526000615b8760a08301856149f7565b8281036080840152610f0081856149f7565b600067ffffffffffffffff808316818103615bb657615bb6615648565b6001019392505050565b600060208284031215615bd257600080fd5b5051919050565b60208152600073ffffffffffffffffffffffffffffffffffffffff808451166020840152806020850151166040840152506040830151610100806060850152615c266101208501836149f7565b91506060850151615c43608086018267ffffffffffffffff169052565b50608085015161ffff811660a08601525060a085015160c085015260c0850151615c7560e086018263ffffffff169052565b5060e08501516bffffffffffffffffffffffff8116858301525090949350505050565b805161495b81614c04565b805161495b8161493a565b805161495b81614fbf565b805161495b81614fdd565b60006101608284031215615cd757600080fd5b615cdf614b44565b615ce8836154ef565b8152615cf660208401615c98565b6020820152615d0760408401615c98565b6040820152615d1860608401615ca3565b6060820152615d29608084016154fa565b6080820152615d3a60a084016154ef565b60a0820152615d4b60c08401615cae565b60c082015260e083015160e0820152610100615d68818501615cb9565b90820152610120615d7a848201615cae565b90820152610140615d8c848201615cae565b908201529392505050565b600073ffffffffffffffffffffffffffffffffffffffff808a168352808916602084015280881660408401525060e06060830152615dd860e08301876149f7565b61ffff9590951660808301525063ffffffff9290921660a08301526bffffffffffffffffffffffff1660c090910152949350505050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260006146b960408301846149f7565b838152606060208201526000615e5760608301856149f7565b8281036040840152615e6981856149f7565b9695505050505050565b60008251615e858184602087016149d3565b919091019291505056fea164736f6c6343000813000a", } var FunctionsRouterABI = FunctionsRouterMetaData.ABI var FunctionsRouterBin = FunctionsRouterMetaData.Bin -func DeployFunctionsRouter(auth *bind.TransactOpts, backend bind.ContractBackend, timelockBlocks uint16, maximumTimelockBlocks uint16, linkToken common.Address, config []byte) (common.Address, *types.Transaction, *FunctionsRouter, error) { +func DeployFunctionsRouter(auth *bind.TransactOpts, backend bind.ContractBackend, timelockBlocks uint16, maximumTimelockBlocks uint16, linkToken common.Address, config IFunctionsRouterConfig) (common.Address, *types.Transaction, *FunctionsRouter, error) { parsed, err := FunctionsRouterMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -229,35 +245,25 @@ func (_FunctionsRouter *FunctionsRouterCallerSession) GetAllowListId() ([32]byte return _FunctionsRouter.Contract.GetAllowListId(&_FunctionsRouter.CallOpts) } -func (_FunctionsRouter *FunctionsRouterCaller) GetConfig(opts *bind.CallOpts) (GetConfig, - - error) { +func (_FunctionsRouter *FunctionsRouterCaller) GetConfig(opts *bind.CallOpts) (IFunctionsRouterConfig, error) { var out []interface{} err := _FunctionsRouter.contract.Call(opts, &out, "getConfig") - outstruct := new(GetConfig) if err != nil { - return *outstruct, err + return *new(IFunctionsRouterConfig), err } - outstruct.MaxConsumersPerSubscription = *abi.ConvertType(out[0], new(uint16)).(*uint16) - outstruct.AdminFee = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - outstruct.HandleOracleFulfillmentSelector = *abi.ConvertType(out[2], new([4]byte)).(*[4]byte) - outstruct.MaxCallbackGasLimits = *abi.ConvertType(out[3], new([]uint32)).(*[]uint32) + out0 := *abi.ConvertType(out[0], new(IFunctionsRouterConfig)).(*IFunctionsRouterConfig) - return *outstruct, err + return out0, err } -func (_FunctionsRouter *FunctionsRouterSession) GetConfig() (GetConfig, - - error) { +func (_FunctionsRouter *FunctionsRouterSession) GetConfig() (IFunctionsRouterConfig, error) { return _FunctionsRouter.Contract.GetConfig(&_FunctionsRouter.CallOpts) } -func (_FunctionsRouter *FunctionsRouterCallerSession) GetConfig() (GetConfig, - - error) { +func (_FunctionsRouter *FunctionsRouterCallerSession) GetConfig() (IFunctionsRouterConfig, error) { return _FunctionsRouter.Contract.GetConfig(&_FunctionsRouter.CallOpts) } @@ -389,37 +395,25 @@ func (_FunctionsRouter *FunctionsRouterCallerSession) GetProposedContractSet() ( return _FunctionsRouter.Contract.GetProposedContractSet(&_FunctionsRouter.CallOpts) } -func (_FunctionsRouter *FunctionsRouterCaller) GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (GetSubscription, - - error) { +func (_FunctionsRouter *FunctionsRouterCaller) GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (IFunctionsSubscriptionsSubscription, error) { var out []interface{} err := _FunctionsRouter.contract.Call(opts, &out, "getSubscription", subscriptionId) - outstruct := new(GetSubscription) if err != nil { - return *outstruct, err + return *new(IFunctionsSubscriptionsSubscription), err } - outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.Owner = *abi.ConvertType(out[1], new(common.Address)).(*common.Address) - outstruct.BlockedBalance = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) - outstruct.RequestedOwner = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) - outstruct.Consumers = *abi.ConvertType(out[4], new([]common.Address)).(*[]common.Address) - outstruct.Flags = *abi.ConvertType(out[5], new([32]byte)).(*[32]byte) + out0 := *abi.ConvertType(out[0], new(IFunctionsSubscriptionsSubscription)).(*IFunctionsSubscriptionsSubscription) - return *outstruct, err + return out0, err } -func (_FunctionsRouter *FunctionsRouterSession) GetSubscription(subscriptionId uint64) (GetSubscription, - - error) { +func (_FunctionsRouter *FunctionsRouterSession) GetSubscription(subscriptionId uint64) (IFunctionsSubscriptionsSubscription, error) { return _FunctionsRouter.Contract.GetSubscription(&_FunctionsRouter.CallOpts, subscriptionId) } -func (_FunctionsRouter *FunctionsRouterCallerSession) GetSubscription(subscriptionId uint64) (GetSubscription, - - error) { +func (_FunctionsRouter *FunctionsRouterCallerSession) GetSubscription(subscriptionId uint64) (IFunctionsSubscriptionsSubscription, error) { return _FunctionsRouter.Contract.GetSubscription(&_FunctionsRouter.CallOpts, subscriptionId) } @@ -755,18 +749,6 @@ func (_FunctionsRouter *FunctionsRouterTransactorSession) ProposeSubscriptionOwn return _FunctionsRouter.Contract.ProposeSubscriptionOwnerTransfer(&_FunctionsRouter.TransactOpts, subscriptionId, newOwner) } -func (_FunctionsRouter *FunctionsRouterTransactor) ProposeTimelockBlocks(opts *bind.TransactOpts, blocks uint16) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "proposeTimelockBlocks", blocks) -} - -func (_FunctionsRouter *FunctionsRouterSession) ProposeTimelockBlocks(blocks uint16) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeTimelockBlocks(&_FunctionsRouter.TransactOpts, blocks) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) ProposeTimelockBlocks(blocks uint16) (*types.Transaction, error) { - return _FunctionsRouter.Contract.ProposeTimelockBlocks(&_FunctionsRouter.TransactOpts, blocks) -} - func (_FunctionsRouter *FunctionsRouterTransactor) RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _FunctionsRouter.contract.Transact(opts, "recoverFunds", to) } @@ -899,18 +881,6 @@ func (_FunctionsRouter *FunctionsRouterTransactorSession) UpdateContracts() (*ty return _FunctionsRouter.Contract.UpdateContracts(&_FunctionsRouter.TransactOpts) } -func (_FunctionsRouter *FunctionsRouterTransactor) UpdateTimelockBlocks(opts *bind.TransactOpts) (*types.Transaction, error) { - return _FunctionsRouter.contract.Transact(opts, "updateTimelockBlocks") -} - -func (_FunctionsRouter *FunctionsRouterSession) UpdateTimelockBlocks() (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateTimelockBlocks(&_FunctionsRouter.TransactOpts) -} - -func (_FunctionsRouter *FunctionsRouterTransactorSession) UpdateTimelockBlocks() (*types.Transaction, error) { - return _FunctionsRouter.Contract.UpdateTimelockBlocks(&_FunctionsRouter.TransactOpts) -} - type FunctionsRouterConfigChangedIterator struct { Event *FunctionsRouterConfigChanged @@ -972,10 +942,8 @@ func (it *FunctionsRouterConfigChangedIterator) Close() error { } type FunctionsRouterConfigChanged struct { - AdminFee *big.Int - HandleOracleFulfillmentSelector [4]byte - MaxCallbackGasLimits []uint32 - Raw types.Log + Arg0 IFunctionsRouterConfig + Raw types.Log } func (_FunctionsRouter *FunctionsRouterFilterer) FilterConfigChanged(opts *bind.FilterOpts) (*FunctionsRouterConfigChangedIterator, error) { @@ -2344,16 +2312,17 @@ func (it *FunctionsRouterRequestStartIterator) Close() error { } type FunctionsRouterRequestStart struct { - RequestId [32]byte - DonId [32]byte - SubscriptionId uint64 - SubscriptionOwner common.Address - RequestingContract common.Address - RequestInitiator common.Address - Data []byte - DataVersion uint16 - CallbackGasLimit uint32 - Raw types.Log + RequestId [32]byte + DonId [32]byte + SubscriptionId uint64 + SubscriptionOwner common.Address + RequestingContract common.Address + RequestInitiator common.Address + Data []byte + DataVersion uint16 + CallbackGasLimit uint32 + EstimatedTotalCostJuels *big.Int + Raw types.Log } func (_FunctionsRouter *FunctionsRouterFilterer) FilterRequestStart(opts *bind.FilterOpts, requestId [][32]byte, donId [][32]byte, subscriptionId []uint64) (*FunctionsRouterRequestStartIterator, error) { @@ -3814,12 +3783,6 @@ func (_FunctionsRouter *FunctionsRouterFilterer) ParseUnpaused(log types.Log) (* return event, nil } -type GetConfig struct { - MaxConsumersPerSubscription uint16 - AdminFee *big.Int - HandleOracleFulfillmentSelector [4]byte - MaxCallbackGasLimits []uint32 -} type GetConsumer struct { Allowed bool InitiatedRequests uint64 @@ -3830,14 +3793,6 @@ type GetProposedContractSet struct { Ids [][32]byte To []common.Address } -type GetSubscription struct { - Balance *big.Int - Owner common.Address - BlockedBalance *big.Int - RequestedOwner common.Address - Consumers []common.Address - Flags [32]byte -} func (_FunctionsRouter *FunctionsRouter) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { @@ -3894,7 +3849,7 @@ func (_FunctionsRouter *FunctionsRouter) ParseLog(log types.Log) (generated.Abig } func (FunctionsRouterConfigChanged) Topic() common.Hash { - return common.HexToHash("0xe6a1eda76d42a6d1d813f26765716562044db1e8bd8be7d088705e64afd301ca") + return common.HexToHash("0x9988860843c5f26e38bf5b1c43b17689b36487e4beb67dbc84264cc5bf417860") } func (FunctionsRouterConfigProposed) Topic() common.Hash { @@ -3938,7 +3893,7 @@ func (FunctionsRouterRequestProcessed) Topic() common.Hash { } func (FunctionsRouterRequestStart) Topic() common.Hash { - return common.HexToHash("0x7c720ccd20069b8311a6be4ba1cf3294d09eb247aa5d73a8502054b6e68a2f54") + return common.HexToHash("0xf67aec45c9a7ede407974a3e0c3a743dffeab99ee3f2d4c9a8144c2ebf2c7ec9") } func (FunctionsRouterRequestTimedOut) Topic() common.Hash { @@ -3994,9 +3949,7 @@ type FunctionsRouterInterface interface { GetAllowListId(opts *bind.CallOpts) ([32]byte, error) - GetConfig(opts *bind.CallOpts) (GetConfig, - - error) + GetConfig(opts *bind.CallOpts) (IFunctionsRouterConfig, error) GetConsumer(opts *bind.CallOpts, client common.Address, subscriptionId uint64) (GetConsumer, @@ -4012,9 +3965,7 @@ type FunctionsRouterInterface interface { error) - GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (GetSubscription, - - error) + GetSubscription(opts *bind.CallOpts, subscriptionId uint64) (IFunctionsSubscriptionsSubscription, error) GetSubscriptionCount(opts *bind.CallOpts) (uint64, error) @@ -4060,8 +4011,6 @@ type FunctionsRouterInterface interface { ProposeSubscriptionOwnerTransfer(opts *bind.TransactOpts, subscriptionId uint64, newOwner common.Address) (*types.Transaction, error) - ProposeTimelockBlocks(opts *bind.TransactOpts, blocks uint16) (*types.Transaction, error) - RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) RemoveConsumer(opts *bind.TransactOpts, subscriptionId uint64, consumer common.Address) (*types.Transaction, error) @@ -4084,8 +4033,6 @@ type FunctionsRouterInterface interface { UpdateContracts(opts *bind.TransactOpts) (*types.Transaction, error) - UpdateTimelockBlocks(opts *bind.TransactOpts) (*types.Transaction, error) - FilterConfigChanged(opts *bind.FilterOpts) (*FunctionsRouterConfigChangedIterator, error) WatchConfigChanged(opts *bind.WatchOpts, sink chan<- *FunctionsRouterConfigChanged) (event.Subscription, error) diff --git a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 05a51012855..afbdedfabb7 100644 --- a/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/functions/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -4,9 +4,9 @@ functions_allow_list: ../../../contracts/solc/v0.8.19/functions/1_0_0/TermsOfSer functions_billing_registry_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsBillingRegistryEventsMock.bin 50deeb883bd9c3729702be335c0388f9d8553bab4be5e26ecacac496a89e2b77 functions_client: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClient.bin 2368f537a04489c720a46733f8596c4fc88a31062ecfa966d05f25dd98608aca functions_client_example: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsClientExample.bin 525316bc1fab9f1d6d262ac9fc1087f66a8314de4dcc9684ba78a29e8014328f -functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin 078a41c5c56dae19be70bf19d15d61cd7dba5a306a58ac8b7b6ccdfe3baf4bd3 +functions_coordinator: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsCoordinator.bin d9eeb059cd99938094bfa15f86d33399c5e0a58d196294bc0ab5148463cc0391 functions_oracle_events_mock: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsOracleEventsMock.bin 3ca70f966f8fe751987f0ccb50bebb6aa5be77e4a9f835d1ae99e0e9bfb7d52c -functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin f14117bbc3f9f50b7098d44c83b3270cb382b7b3cc4047bc645baf7224420f32 +functions_router: ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.abi ../../../contracts/solc/v0.8.19/functions/1_0_0/FunctionsRouter.bin c9de640eefd95cca557cc482a35f4bad477455665996c944d05fcbdd9207813b ocr2dr: ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/Functions.bin d9a794b33f47cc57563d216f7cf3a612309fc3062356a27e30005cf1d59e449d ocr2dr_client: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClient.bin 84aa63f9dbc5c7eac240db699b09e613ca4c6cd56dab10bdc25b02461b717e21 ocr2dr_client_example: ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClientExample.abi ../../../contracts/solc/v0.8.6/functions/0_0_0/FunctionsClientExample.bin a978d9b52a5a2da19eef0975979de256e62980a0cfb3084fe6d66a351b4ef534 diff --git a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go index 5d73912aa55..abed26e1996 100644 --- a/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go +++ b/core/services/ocr2/plugins/functions/integration_tests/v1/internal/testutils.go @@ -179,20 +179,15 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, require.NoError(t, err) uint80Type, err := abi.NewType("uint80", "uint80", nil) require.NoError(t, err) - uint96Type, err := abi.NewType("uint96", "uint96", nil) - require.NoError(t, err) uint256Type, err := abi.NewType("uint256", "uint256", nil) require.NoError(t, err) int256Type, err := abi.NewType("int256", "int256", nil) require.NoError(t, err) - bytes4Type, err := abi.NewType("bytes4", "bytes4", nil) require.NoError(t, err) boolType, err := abi.NewType("bool", "bool", nil) require.NoError(t, err) addressType, err := abi.NewType("address", "address", nil) require.NoError(t, err) - uint32ArrType, err := abi.NewType("uint32[]", "uint32[]", nil) - require.NoError(t, err) // Deploy LINK token linkAddr, _, linkToken, err := link_token_interface.DeployLinkToken(owner, b) @@ -203,12 +198,6 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, require.NoError(t, err) // Deploy Router contract - routerConfigABI := abi.Arguments{ - {Type: uint16Type}, // maxConsumers - {Type: uint96Type}, // adminFee - {Type: bytes4Type}, // handleOracleFulfillmentSelector - {Type: uint32ArrType}, // maxCallbackGasLimits - } var maxConsumers = uint16(100) var adminFee = big.NewInt(0) handleOracleFulfillmentSelectorSlice, err := hex.DecodeString("0ca76175") @@ -216,11 +205,10 @@ func StartNewChainWithContracts(t *testing.T, nClients int) (*bind.TransactOpts, var handleOracleFulfillmentSelector [4]byte copy(handleOracleFulfillmentSelector[:], handleOracleFulfillmentSelectorSlice[:4]) maxCallbackGasLimits := []uint32{300_000, 500_000, 1_000_000} - routerConfig, err := routerConfigABI.Pack(maxConsumers, adminFee, handleOracleFulfillmentSelector, maxCallbackGasLimits) require.NoError(t, err) var timelockBlocks = uint16(0) var maximumTimelockBlocks = uint16(10) - routerAddress, _, routerContract, err := functions_router.DeployFunctionsRouter(owner, b, timelockBlocks, maximumTimelockBlocks, linkAddr, routerConfig) + routerAddress, _, routerContract, err := functions_router.DeployFunctionsRouter(owner, b, timelockBlocks, maximumTimelockBlocks, linkAddr, functions_router.IFunctionsRouterConfig{maxConsumers, adminFee, handleOracleFulfillmentSelector, maxCallbackGasLimits}) require.NoError(t, err) // Deploy Allow List contract