编译器
0.8.19+commit.7dd6d404
文件 1 的 20:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 20:ConfirmedOwner.sol
pragma solidity ^0.8.0;
import {ConfirmedOwnerWithProposal} from "./ConfirmedOwnerWithProposal.sol";
contract ConfirmedOwner is ConfirmedOwnerWithProposal {
constructor(address newOwner) ConfirmedOwnerWithProposal(newOwner, address(0)) {}
}
文件 3 的 20:ConfirmedOwnerWithProposal.sol
pragma solidity ^0.8.0;
import {IOwnable} from "../interfaces/IOwnable.sol";
contract ConfirmedOwnerWithProposal is IOwnable {
address private s_owner;
address private s_pendingOwner;
event OwnershipTransferRequested(address indexed from, address indexed to);
event OwnershipTransferred(address indexed from, address indexed to);
constructor(address newOwner, address pendingOwner) {
require(newOwner != address(0), "Cannot set owner to zero");
s_owner = newOwner;
if (pendingOwner != address(0)) {
_transferOwnership(pendingOwner);
}
}
function transferOwnership(address to) public override onlyOwner {
_transferOwnership(to);
}
function acceptOwnership() external override {
require(msg.sender == s_pendingOwner, "Must be proposed owner");
address oldOwner = s_owner;
s_owner = msg.sender;
s_pendingOwner = address(0);
emit OwnershipTransferred(oldOwner, msg.sender);
}
function owner() public view override returns (address) {
return s_owner;
}
function _transferOwnership(address to) private {
require(to != msg.sender, "Cannot transfer to self");
s_pendingOwner = to;
emit OwnershipTransferRequested(s_owner, to);
}
function _validateOwnership() internal view {
require(msg.sender == s_owner, "Only callable by owner");
}
modifier onlyOwner() {
_validateOwnership();
_;
}
}
文件 4 的 20:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 5 的 20:FunctionsResponse.sol
pragma solidity ^0.8.19;
library FunctionsResponse {
struct RequestMeta {
bytes data;
bytes32 flags;
address requestingContract;
uint96 availableBalance;
uint72 adminFee;
uint64 subscriptionId;
uint64 initiatedRequests;
uint32 callbackGasLimit;
uint16 dataVersion;
uint64 completedRequests;
address subscriptionOwner;
}
enum FulfillResult {
FULFILLED,
USER_CALLBACK_ERROR,
INVALID_REQUEST_ID,
COST_EXCEEDS_COMMITMENT,
INSUFFICIENT_GAS_PROVIDED,
SUBSCRIPTION_BALANCE_INVARIANT_VIOLATION,
INVALID_COMMITMENT
}
struct Commitment {
bytes32 requestId;
address coordinator;
uint96 estimatedTotalCostJuels;
address client;
uint64 subscriptionId;
uint32 callbackGasLimit;
uint72 adminFee;
uint72 donFee;
uint40 gasOverheadBeforeCallback;
uint40 gasOverheadAfterCallback;
uint32 timeoutTimestamp;
}
}
文件 6 的 20:FunctionsRouter.sol
pragma solidity ^0.8.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 {FunctionsSubscriptions} from "./FunctionsSubscriptions.sol";
import {FunctionsResponse} from "./libraries/FunctionsResponse.sol";
import {ConfirmedOwner} from "../../../shared/access/ConfirmedOwner.sol";
import {SafeCast} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/utils/math/SafeCast.sol";
import {Pausable} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/security/Pausable.sol";
contract FunctionsRouter is IFunctionsRouter, FunctionsSubscriptions, Pausable, ITypeAndVersion, ConfirmedOwner {
using FunctionsResponse for FunctionsResponse.RequestMeta;
using FunctionsResponse for FunctionsResponse.Commitment;
using FunctionsResponse for FunctionsResponse.FulfillResult;
string public constant override typeAndVersion = "Functions Router v1.0.0";
uint16 public constant MAX_CALLBACK_RETURN_BYTES = 4 + 4 * 32;
uint8 private constant MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX = 0;
event RequestStart(
bytes32 indexed requestId,
bytes32 indexed donId,
uint64 indexed subscriptionId,
address subscriptionOwner,
address requestingContract,
address requestInitiator,
bytes data,
uint16 dataVersion,
uint32 callbackGasLimit,
uint96 estimatedTotalCostJuels
);
event RequestProcessed(
bytes32 indexed requestId,
uint64 indexed subscriptionId,
uint96 totalCostJuels,
address transmitter,
FunctionsResponse.FulfillResult resultCode,
bytes response,
bytes err,
bytes callbackReturnData
);
event RequestNotProcessed(
bytes32 indexed requestId,
address coordinator,
address transmitter,
FunctionsResponse.FulfillResult resultCode
);
error EmptyRequestData();
error OnlyCallableFromCoordinator();
error SenderMustAcceptTermsOfService(address sender);
error InvalidGasFlagValue(uint8 value);
error GasLimitTooBig(uint32 limit);
error DuplicateRequestId(bytes32 requestId);
struct CallbackResult {
bool success;
uint256 gasUsed;
bytes returnData;
}
mapping(bytes32 id => address routableContract) private s_route;
error RouteNotFound(bytes32 id);
bytes32 private s_allowListId;
struct Config {
uint16 maxConsumersPerSubscription;
uint72 adminFee;
bytes4 handleOracleFulfillmentSelector;
uint16 gasForCallExactCheck;
uint32[] maxCallbackGasLimits;
uint16 subscriptionDepositMinimumRequests;
uint72 subscriptionDepositJuels;
}
Config private s_config;
event ConfigUpdated(Config);
uint8 private constant MAX_PROPOSAL_SET_LENGTH = 8;
struct ContractProposalSet {
bytes32[] ids;
address[] to;
}
ContractProposalSet private s_proposedContractSet;
event ContractProposed(
bytes32 proposedContractSetId,
address proposedContractSetFromAddress,
address proposedContractSetToAddress
);
event ContractUpdated(bytes32 id, address from, address to);
error InvalidProposal();
error IdentifierIsReserved(bytes32 id);
constructor(
address linkToken,
Config memory config
) FunctionsSubscriptions(linkToken) ConfirmedOwner(msg.sender) Pausable() {
updateConfig(config);
}
function getConfig() external view returns (Config memory) {
return s_config;
}
function updateConfig(Config memory config) public onlyOwner {
s_config = config;
emit ConfigUpdated(config);
}
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);
}
}
function getAdminFee() external view override returns (uint72) {
return s_config.adminFee;
}
function getAllowListId() external view override returns (bytes32) {
return s_allowListId;
}
function setAllowListId(bytes32 allowListId) external override onlyOwner {
s_allowListId = allowListId;
}
function _getMaxConsumers() internal view override returns (uint16) {
return s_config.maxConsumersPerSubscription;
}
function _getSubscriptionDepositDetails() internal view override returns (uint16, uint72) {
return (s_config.subscriptionDepositMinimumRequests, s_config.subscriptionDepositJuels);
}
function sendRequest(
uint64 subscriptionId,
bytes calldata data,
uint16 dataVersion,
uint32 callbackGasLimit,
bytes32 donId
) external override returns (bytes32) {
IFunctionsCoordinator coordinator = IFunctionsCoordinator(getContractById(donId));
return _sendRequest(donId, coordinator, subscriptionId, data, dataVersion, callbackGasLimit);
}
function sendRequestToProposed(
uint64 subscriptionId,
bytes calldata data,
uint16 dataVersion,
uint32 callbackGasLimit,
bytes32 donId
) external override returns (bytes32) {
IFunctionsCoordinator coordinator = IFunctionsCoordinator(getProposedContractById(donId));
return _sendRequest(donId, coordinator, subscriptionId, data, dataVersion, callbackGasLimit);
}
function _sendRequest(
bytes32 donId,
IFunctionsCoordinator coordinator,
uint64 subscriptionId,
bytes memory data,
uint16 dataVersion,
uint32 callbackGasLimit
) private returns (bytes32) {
_whenNotPaused();
_isExistingSubscription(subscriptionId);
_isAllowedConsumer(msg.sender, subscriptionId);
isValidCallbackGasLimit(subscriptionId, callbackGasLimit);
if (data.length == 0) {
revert EmptyRequestData();
}
Subscription memory subscription = getSubscription(subscriptionId);
Consumer memory consumer = getConsumer(msg.sender, subscriptionId);
uint72 adminFee = s_config.adminFee;
FunctionsResponse.Commitment memory commitment = coordinator.startRequest(
FunctionsResponse.RequestMeta({
requestingContract: msg.sender,
data: data,
subscriptionId: subscriptionId,
dataVersion: dataVersion,
flags: getFlags(subscriptionId),
callbackGasLimit: callbackGasLimit,
adminFee: adminFee,
initiatedRequests: consumer.initiatedRequests,
completedRequests: consumer.completedRequests,
availableBalance: subscription.balance - subscription.blockedBalance,
subscriptionOwner: subscription.owner
})
);
if (s_requestCommitments[commitment.requestId] != bytes32(0)) {
revert DuplicateRequestId(commitment.requestId);
}
s_requestCommitments[commitment.requestId] = keccak256(
abi.encode(
FunctionsResponse.Commitment({
adminFee: adminFee,
coordinator: address(coordinator),
client: msg.sender,
subscriptionId: subscriptionId,
callbackGasLimit: callbackGasLimit,
estimatedTotalCostJuels: commitment.estimatedTotalCostJuels,
timeoutTimestamp: commitment.timeoutTimestamp,
requestId: commitment.requestId,
donFee: commitment.donFee,
gasOverheadBeforeCallback: commitment.gasOverheadBeforeCallback,
gasOverheadAfterCallback: commitment.gasOverheadAfterCallback
})
)
);
_markRequestInFlight(msg.sender, subscriptionId, commitment.estimatedTotalCostJuels);
emit RequestStart({
requestId: commitment.requestId,
donId: donId,
subscriptionId: subscriptionId,
subscriptionOwner: subscription.owner,
requestingContract: msg.sender,
requestInitiator: tx.origin,
data: data,
dataVersion: dataVersion,
callbackGasLimit: callbackGasLimit,
estimatedTotalCostJuels: commitment.estimatedTotalCostJuels
});
return commitment.requestId;
}
function fulfill(
bytes memory response,
bytes memory err,
uint96 juelsPerGas,
uint96 costWithoutCallback,
address transmitter,
FunctionsResponse.Commitment memory commitment
) external override returns (FunctionsResponse.FulfillResult resultCode, uint96) {
_whenNotPaused();
if (msg.sender != commitment.coordinator) {
revert OnlyCallableFromCoordinator();
}
{
bytes32 commitmentHash = s_requestCommitments[commitment.requestId];
if (commitmentHash == bytes32(0)) {
resultCode = FunctionsResponse.FulfillResult.INVALID_REQUEST_ID;
emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode);
return (resultCode, 0);
}
if (keccak256(abi.encode(commitment)) != commitmentHash) {
resultCode = FunctionsResponse.FulfillResult.INVALID_COMMITMENT;
emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode);
return (resultCode, 0);
}
if (gasleft() < commitment.callbackGasLimit + commitment.gasOverheadAfterCallback) {
resultCode = FunctionsResponse.FulfillResult.INSUFFICIENT_GAS_PROVIDED;
emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode);
return (resultCode, 0);
}
}
{
uint96 callbackCost = juelsPerGas * SafeCast.toUint96(commitment.callbackGasLimit);
uint96 totalCostJuels = commitment.adminFee + costWithoutCallback + callbackCost;
if (totalCostJuels > getSubscription(commitment.subscriptionId).balance) {
resultCode = FunctionsResponse.FulfillResult.SUBSCRIPTION_BALANCE_INVARIANT_VIOLATION;
emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode);
return (resultCode, 0);
}
if (totalCostJuels > commitment.estimatedTotalCostJuels) {
resultCode = FunctionsResponse.FulfillResult.COST_EXCEEDS_COMMITMENT;
emit RequestNotProcessed(commitment.requestId, commitment.coordinator, transmitter, resultCode);
return (resultCode, 0);
}
}
delete s_requestCommitments[commitment.requestId];
CallbackResult memory result = _callback(
commitment.requestId,
response,
err,
commitment.callbackGasLimit,
commitment.client
);
resultCode = result.success
? FunctionsResponse.FulfillResult.FULFILLED
: FunctionsResponse.FulfillResult.USER_CALLBACK_ERROR;
Receipt memory receipt = _pay(
commitment.subscriptionId,
commitment.estimatedTotalCostJuels,
commitment.client,
commitment.adminFee,
juelsPerGas,
SafeCast.toUint96(result.gasUsed),
costWithoutCallback
);
emit RequestProcessed({
requestId: commitment.requestId,
subscriptionId: commitment.subscriptionId,
totalCostJuels: receipt.totalCostJuels,
transmitter: transmitter,
resultCode: resultCode,
response: response,
err: err,
callbackReturnData: result.returnData
});
return (resultCode, receipt.callbackGasCostJuels);
}
function _callback(
bytes32 requestId,
bytes memory response,
bytes memory err,
uint32 callbackGasLimit,
address client
) private returns (CallbackResult memory) {
bool destinationNoLongerExists;
assembly {
destinationNoLongerExists := iszero(extcodesize(client))
}
if (destinationNoLongerExists) {
return CallbackResult({success: false, gasUsed: 0, returnData: new bytes(0)});
}
bytes memory encodedCallback = abi.encodeWithSelector(
s_config.handleOracleFulfillmentSelector,
requestId,
response,
err
);
uint16 gasForCallExactCheck = s_config.gasForCallExactCheck;
bool success;
uint256 gasUsed;
bytes memory returnData = new bytes(MAX_CALLBACK_RETURN_BYTES);
assembly {
let g := gas()
if lt(g, gasForCallExactCheck) {
revert(0, 0)
}
g := sub(g, gasForCallExactCheck)
if iszero(gt(sub(g, div(g, 64)), callbackGasLimit)) {
revert(0, 0)
}
let gasBeforeCall := gas()
success := call(callbackGasLimit, client, 0, add(encodedCallback, 0x20), mload(encodedCallback), 0, 0)
gasUsed := sub(gasBeforeCall, gas())
let toCopy := returndatasize()
if gt(toCopy, MAX_CALLBACK_RETURN_BYTES) {
toCopy := MAX_CALLBACK_RETURN_BYTES
}
mstore(returnData, toCopy)
returndatacopy(add(returnData, 0x20), 0, toCopy)
}
return CallbackResult({success: success, gasUsed: gasUsed, returnData: returnData});
}
function getContractById(bytes32 id) public view override returns (address) {
address currentImplementation = s_route[id];
if (currentImplementation == address(0)) {
revert RouteNotFound(id);
}
return currentImplementation;
}
function getProposedContractById(bytes32 id) public view override returns (address) {
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 getProposedContractSet() external view override returns (bytes32[] memory, address[] memory) {
return (s_proposedContractSet.ids, s_proposedContractSet.to);
}
function proposeContractsUpdate(
bytes32[] memory proposedContractSetIds,
address[] memory proposedContractSetAddresses
) external override onlyOwner {
uint256 idsArrayLength = proposedContractSetIds.length;
if (idsArrayLength != proposedContractSetAddresses.length || idsArrayLength > MAX_PROPOSAL_SET_LENGTH) {
revert InvalidProposal();
}
for (uint256 i = 0; i < idsArrayLength; ++i) {
bytes32 id = proposedContractSetIds[i];
address proposedContract = proposedContractSetAddresses[i];
if (
proposedContract == address(0) ||
s_route[id] == proposedContract
) {
revert InvalidProposal();
}
emit ContractProposed({
proposedContractSetId: id,
proposedContractSetFromAddress: s_route[id],
proposedContractSetToAddress: proposedContract
});
}
s_proposedContractSet = ContractProposalSet({ids: proposedContractSetIds, to: proposedContractSetAddresses});
}
function updateContracts() external override onlyOwner {
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;
}
function _whenNotPaused() internal view override {
_requireNotPaused();
}
function _onlyRouterOwner() internal view override {
_validateOwnership();
}
function _onlySenderThatAcceptedToS() internal view override {
address currentImplementation = s_route[s_allowListId];
if (currentImplementation == address(0)) {
return;
}
if (!IAccessController(currentImplementation).hasAccess(msg.sender, new bytes(0))) {
revert SenderMustAcceptTermsOfService(msg.sender);
}
}
function pause() external override onlyOwner {
_pause();
}
function unpause() external override onlyOwner {
_unpause();
}
}
文件 7 的 20:FunctionsSubscriptions.sol
pragma solidity ^0.8.19;
import {IFunctionsSubscriptions} from "./interfaces/IFunctionsSubscriptions.sol";
import {IERC677Receiver} from "../../../shared/interfaces/IERC677Receiver.sol";
import {IFunctionsBilling} from "./interfaces/IFunctionsBilling.sol";
import {FunctionsResponse} from "./libraries/FunctionsResponse.sol";
import {IERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "../../../vendor/openzeppelin-solidity/v4.8.3/contracts/token/ERC20/utils/SafeERC20.sol";
abstract contract FunctionsSubscriptions is IFunctionsSubscriptions, IERC677Receiver {
using SafeERC20 for IERC20;
using FunctionsResponse for FunctionsResponse.Commitment;
IERC20 internal immutable i_linkToken;
uint96 private s_totalLinkBalance;
mapping(address coordinator => uint96 balanceJuelsLink) private s_withdrawableTokens;
uint64 private s_currentSubscriptionId;
mapping(uint64 subscriptionId => Subscription) private s_subscriptions;
mapping(address consumer => mapping(uint64 subscriptionId => Consumer)) private s_consumers;
event SubscriptionCreated(uint64 indexed subscriptionId, address owner);
event SubscriptionFunded(uint64 indexed subscriptionId, uint256 oldBalance, uint256 newBalance);
event SubscriptionConsumerAdded(uint64 indexed subscriptionId, address consumer);
event SubscriptionConsumerRemoved(uint64 indexed subscriptionId, address consumer);
event SubscriptionCanceled(uint64 indexed subscriptionId, address fundsRecipient, uint256 fundsAmount);
event SubscriptionOwnerTransferRequested(uint64 indexed subscriptionId, address from, address to);
event SubscriptionOwnerTransferred(uint64 indexed subscriptionId, address from, address to);
error TooManyConsumers(uint16 maximumConsumers);
error InsufficientBalance(uint96 currentBalanceJuels);
error InvalidConsumer();
error CannotRemoveWithPendingRequests();
error InvalidSubscription();
error OnlyCallableFromLink();
error InvalidCalldata();
error MustBeSubscriptionOwner();
error TimeoutNotExceeded();
error MustBeProposedOwner(address proposedOwner);
event FundsRecovered(address to, uint256 amount);
mapping(bytes32 requestId => bytes32 commitmentHash) internal s_requestCommitments;
struct Receipt {
uint96 callbackGasCostJuels;
uint96 totalCostJuels;
}
event RequestTimedOut(bytes32 indexed requestId);
constructor(address link) {
i_linkToken = IERC20(link);
}
function _markRequestInFlight(address client, uint64 subscriptionId, uint96 estimatedTotalCostJuels) internal {
s_subscriptions[subscriptionId].blockedBalance += estimatedTotalCostJuels;
s_consumers[client][subscriptionId].initiatedRequests += 1;
}
function _pay(
uint64 subscriptionId,
uint96 estimatedTotalCostJuels,
address client,
uint96 adminFee,
uint96 juelsPerGas,
uint96 gasUsed,
uint96 costWithoutCallbackJuels
) internal returns (Receipt memory) {
uint96 callbackGasCostJuels = juelsPerGas * gasUsed;
uint96 totalCostJuels = costWithoutCallbackJuels + adminFee + callbackGasCostJuels;
if (
s_subscriptions[subscriptionId].balance < totalCostJuels ||
s_subscriptions[subscriptionId].blockedBalance < estimatedTotalCostJuels
) {
revert InsufficientBalance(s_subscriptions[subscriptionId].balance);
}
s_subscriptions[subscriptionId].balance -= totalCostJuels;
s_subscriptions[subscriptionId].blockedBalance -= estimatedTotalCostJuels;
s_withdrawableTokens[msg.sender] += costWithoutCallbackJuels + callbackGasCostJuels;
s_withdrawableTokens[address(this)] += adminFee;
s_consumers[client][subscriptionId].completedRequests += 1;
return Receipt({callbackGasCostJuels: callbackGasCostJuels, totalCostJuels: totalCostJuels});
}
function ownerCancelSubscription(uint64 subscriptionId) external override {
_onlyRouterOwner();
_isExistingSubscription(subscriptionId);
_cancelSubscriptionHelper(subscriptionId, s_subscriptions[subscriptionId].owner, false);
}
function recoverFunds(address to) external override {
_onlyRouterOwner();
uint256 externalBalance = i_linkToken.balanceOf(address(this));
uint256 internalBalance = uint256(s_totalLinkBalance);
if (internalBalance < externalBalance) {
uint256 amount = externalBalance - internalBalance;
i_linkToken.safeTransfer(to, amount);
emit FundsRecovered(to, amount);
}
}
function oracleWithdraw(address recipient, uint96 amount) external override {
_whenNotPaused();
if (amount == 0) {
revert InvalidCalldata();
}
uint96 currentBalance = s_withdrawableTokens[msg.sender];
if (currentBalance < amount) {
revert InsufficientBalance(currentBalance);
}
s_withdrawableTokens[msg.sender] -= amount;
s_totalLinkBalance -= amount;
i_linkToken.safeTransfer(recipient, amount);
}
function ownerWithdraw(address recipient, uint96 amount) external {
_onlyRouterOwner();
if (amount == 0) {
amount = s_withdrawableTokens[address(this)];
}
uint96 currentBalance = s_withdrawableTokens[address(this)];
if (currentBalance < amount) {
revert InsufficientBalance(currentBalance);
}
s_withdrawableTokens[address(this)] -= amount;
s_totalLinkBalance -= amount;
i_linkToken.safeTransfer(recipient, amount);
}
function onTokenTransfer(address , uint256 amount, bytes calldata data) external override {
_whenNotPaused();
if (msg.sender != address(i_linkToken)) {
revert OnlyCallableFromLink();
}
if (data.length != 32) {
revert InvalidCalldata();
}
uint64 subscriptionId = abi.decode(data, (uint64));
if (s_subscriptions[subscriptionId].owner == address(0)) {
revert InvalidSubscription();
}
uint256 oldBalance = s_subscriptions[subscriptionId].balance;
s_subscriptions[subscriptionId].balance += uint96(amount);
s_totalLinkBalance += uint96(amount);
emit SubscriptionFunded(subscriptionId, oldBalance, oldBalance + amount);
}
function getTotalBalance() external view override returns (uint96) {
return s_totalLinkBalance;
}
function getSubscriptionCount() external view override returns (uint64) {
return s_currentSubscriptionId;
}
function getSubscription(uint64 subscriptionId) public view override returns (Subscription memory) {
_isExistingSubscription(subscriptionId);
return s_subscriptions[subscriptionId];
}
function getSubscriptionsInRange(
uint64 subscriptionIdStart,
uint64 subscriptionIdEnd
) external view override returns (Subscription[] memory subscriptions) {
if (
subscriptionIdStart > subscriptionIdEnd ||
subscriptionIdEnd > s_currentSubscriptionId ||
s_currentSubscriptionId == 0
) {
revert InvalidCalldata();
}
subscriptions = new Subscription[]((subscriptionIdEnd - subscriptionIdStart) + 1);
for (uint256 i = 0; i <= subscriptionIdEnd - subscriptionIdStart; ++i) {
subscriptions[i] = s_subscriptions[uint64(subscriptionIdStart + i)];
}
return subscriptions;
}
function getConsumer(address client, uint64 subscriptionId) public view override returns (Consumer memory) {
return s_consumers[client][subscriptionId];
}
function _isExistingSubscription(uint64 subscriptionId) internal view {
if (s_subscriptions[subscriptionId].owner == address(0)) {
revert InvalidSubscription();
}
}
function _isAllowedConsumer(address client, uint64 subscriptionId) internal view {
if (!s_consumers[client][subscriptionId].allowed) {
revert InvalidConsumer();
}
}
function createSubscription() external override returns (uint64 subscriptionId) {
_whenNotPaused();
_onlySenderThatAcceptedToS();
subscriptionId = ++s_currentSubscriptionId;
s_subscriptions[subscriptionId] = Subscription({
balance: 0,
blockedBalance: 0,
owner: msg.sender,
proposedOwner: address(0),
consumers: new address[](0),
flags: bytes32(0)
});
emit SubscriptionCreated(subscriptionId, msg.sender);
return subscriptionId;
}
function createSubscriptionWithConsumer(address consumer) external override returns (uint64 subscriptionId) {
_whenNotPaused();
_onlySenderThatAcceptedToS();
subscriptionId = ++s_currentSubscriptionId;
s_subscriptions[subscriptionId] = Subscription({
balance: 0,
blockedBalance: 0,
owner: msg.sender,
proposedOwner: address(0),
consumers: new address[](0),
flags: bytes32(0)
});
s_subscriptions[subscriptionId].consumers.push(consumer);
s_consumers[consumer][subscriptionId].allowed = true;
emit SubscriptionCreated(subscriptionId, msg.sender);
emit SubscriptionConsumerAdded(subscriptionId, consumer);
return subscriptionId;
}
function proposeSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external override {
_whenNotPaused();
_onlySubscriptionOwner(subscriptionId);
_onlySenderThatAcceptedToS();
if (newOwner == address(0) || s_subscriptions[subscriptionId].proposedOwner == newOwner) {
revert InvalidCalldata();
}
s_subscriptions[subscriptionId].proposedOwner = newOwner;
emit SubscriptionOwnerTransferRequested(subscriptionId, msg.sender, newOwner);
}
function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external override {
_whenNotPaused();
_onlySenderThatAcceptedToS();
address previousOwner = s_subscriptions[subscriptionId].owner;
address proposedOwner = s_subscriptions[subscriptionId].proposedOwner;
if (proposedOwner != msg.sender) {
revert MustBeProposedOwner(proposedOwner);
}
s_subscriptions[subscriptionId].owner = msg.sender;
s_subscriptions[subscriptionId].proposedOwner = address(0);
emit SubscriptionOwnerTransferred(subscriptionId, previousOwner, msg.sender);
}
function removeConsumer(uint64 subscriptionId, address consumer) external override {
_whenNotPaused();
_onlySubscriptionOwner(subscriptionId);
_onlySenderThatAcceptedToS();
Consumer memory consumerData = s_consumers[consumer][subscriptionId];
_isAllowedConsumer(consumer, subscriptionId);
if (consumerData.initiatedRequests != consumerData.completedRequests) {
revert CannotRemoveWithPendingRequests();
}
address[] memory consumers = s_subscriptions[subscriptionId].consumers;
for (uint256 i = 0; i < consumers.length; ++i) {
if (consumers[i] == consumer) {
s_subscriptions[subscriptionId].consumers[i] = consumers[consumers.length - 1];
s_subscriptions[subscriptionId].consumers.pop();
break;
}
}
delete s_consumers[consumer][subscriptionId];
emit SubscriptionConsumerRemoved(subscriptionId, consumer);
}
function _getMaxConsumers() internal view virtual returns (uint16);
function addConsumer(uint64 subscriptionId, address consumer) external override {
_whenNotPaused();
_onlySubscriptionOwner(subscriptionId);
_onlySenderThatAcceptedToS();
uint16 maximumConsumers = _getMaxConsumers();
if (s_subscriptions[subscriptionId].consumers.length >= maximumConsumers) {
revert TooManyConsumers(maximumConsumers);
}
if (s_consumers[consumer][subscriptionId].allowed) {
return;
}
s_consumers[consumer][subscriptionId].allowed = true;
s_subscriptions[subscriptionId].consumers.push(consumer);
emit SubscriptionConsumerAdded(subscriptionId, consumer);
}
function _getSubscriptionDepositDetails() internal virtual returns (uint16, uint72);
function _cancelSubscriptionHelper(uint64 subscriptionId, address toAddress, bool checkDepositRefundability) private {
Subscription memory subscription = s_subscriptions[subscriptionId];
uint96 balance = subscription.balance;
uint64 completedRequests = 0;
for (uint256 i = 0; i < subscription.consumers.length; ++i) {
address consumer = subscription.consumers[i];
completedRequests += s_consumers[consumer][subscriptionId].completedRequests;
delete s_consumers[consumer][subscriptionId];
}
delete s_subscriptions[subscriptionId];
(uint16 subscriptionDepositMinimumRequests, uint72 subscriptionDepositJuels) = _getSubscriptionDepositDetails();
if (checkDepositRefundability && completedRequests < subscriptionDepositMinimumRequests) {
uint96 deposit = subscriptionDepositJuels > balance ? balance : subscriptionDepositJuels;
if (deposit > 0) {
s_withdrawableTokens[address(this)] += deposit;
balance -= deposit;
}
}
if (balance > 0) {
s_totalLinkBalance -= balance;
i_linkToken.safeTransfer(toAddress, uint256(balance));
}
emit SubscriptionCanceled(subscriptionId, toAddress, balance);
}
function cancelSubscription(uint64 subscriptionId, address to) external override {
_whenNotPaused();
_onlySubscriptionOwner(subscriptionId);
_onlySenderThatAcceptedToS();
if (pendingRequestExists(subscriptionId)) {
revert CannotRemoveWithPendingRequests();
}
_cancelSubscriptionHelper(subscriptionId, to, true);
}
function pendingRequestExists(uint64 subscriptionId) public view override returns (bool) {
address[] memory consumers = s_subscriptions[subscriptionId].consumers;
for (uint256 i = 0; i < consumers.length; ++i) {
Consumer memory consumer = s_consumers[consumers[i]][subscriptionId];
if (consumer.initiatedRequests != consumer.completedRequests) {
return true;
}
}
return false;
}
function setFlags(uint64 subscriptionId, bytes32 flags) external override {
_onlyRouterOwner();
_isExistingSubscription(subscriptionId);
s_subscriptions[subscriptionId].flags = flags;
}
function getFlags(uint64 subscriptionId) public view returns (bytes32) {
return s_subscriptions[subscriptionId].flags;
}
function timeoutRequests(FunctionsResponse.Commitment[] calldata requestsToTimeoutByCommitment) external override {
_whenNotPaused();
for (uint256 i = 0; i < requestsToTimeoutByCommitment.length; ++i) {
FunctionsResponse.Commitment memory request = requestsToTimeoutByCommitment[i];
bytes32 requestId = request.requestId;
uint64 subscriptionId = request.subscriptionId;
if (keccak256(abi.encode(request)) != s_requestCommitments[requestId]) {
revert InvalidCalldata();
}
if (block.timestamp < request.timeoutTimestamp) {
revert TimeoutNotExceeded();
}
IFunctionsBilling(request.coordinator).deleteCommitment(requestId);
s_subscriptions[subscriptionId].blockedBalance -= request.estimatedTotalCostJuels;
s_consumers[request.client][subscriptionId].completedRequests += 1;
delete s_requestCommitments[requestId];
emit RequestTimedOut(requestId);
}
}
function _onlySubscriptionOwner(uint64 subscriptionId) internal view {
address owner = s_subscriptions[subscriptionId].owner;
if (owner == address(0)) {
revert InvalidSubscription();
}
if (msg.sender != owner) {
revert MustBeSubscriptionOwner();
}
}
function _onlySenderThatAcceptedToS() internal virtual;
function _onlyRouterOwner() internal virtual;
function _whenNotPaused() internal virtual;
}
文件 8 的 20:IAccessController.sol
pragma solidity ^0.8.0;
interface IAccessController {
function hasAccess(address user, bytes calldata data) external view returns (bool);
}
文件 9 的 20:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 10 的 20:IERC677Receiver.sol
pragma solidity ^0.8.6;
interface IERC677Receiver {
function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external;
}
文件 11 的 20:IFunctionsBilling.sol
pragma solidity ^0.8.19;
interface IFunctionsBilling {
function getWeiPerUnitLink() external view returns (uint256);
function getDONFee(bytes memory requestCBOR) external view returns (uint72);
function getAdminFee() external view returns (uint72);
function estimateCost(
uint64 subscriptionId,
bytes calldata data,
uint32 callbackGasLimit,
uint256 gasPriceWei
) external view returns (uint96);
function deleteCommitment(bytes32 requestId) external;
function oracleWithdraw(address recipient, uint96 amount) external;
function oracleWithdrawAll() external;
}
文件 12 的 20:IFunctionsCoordinator.sol
pragma solidity ^0.8.19;
import {FunctionsResponse} from "../libraries/FunctionsResponse.sol";
interface IFunctionsCoordinator {
function getThresholdPublicKey() external view returns (bytes memory);
function setThresholdPublicKey(bytes calldata thresholdPublicKey) external;
function getDONPublicKey() external view returns (bytes memory);
function setDONPublicKey(bytes calldata donPublicKey) external;
function startRequest(
FunctionsResponse.RequestMeta calldata request
) external returns (FunctionsResponse.Commitment memory commitment);
}
文件 13 的 20:IFunctionsRouter.sol
pragma solidity ^0.8.19;
import {FunctionsResponse} from "../libraries/FunctionsResponse.sol";
interface IFunctionsRouter {
function getAllowListId() external view returns (bytes32);
function setAllowListId(bytes32 allowListId) external;
function getAdminFee() external view returns (uint72 adminFee);
function sendRequest(
uint64 subscriptionId,
bytes calldata data,
uint16 dataVersion,
uint32 callbackGasLimit,
bytes32 donId
) external returns (bytes32);
function sendRequestToProposed(
uint64 subscriptionId,
bytes calldata data,
uint16 dataVersion,
uint32 callbackGasLimit,
bytes32 donId
) external returns (bytes32);
function fulfill(
bytes memory response,
bytes memory err,
uint96 juelsPerGas,
uint96 costWithoutFulfillment,
address transmitter,
FunctionsResponse.Commitment memory commitment
) external returns (FunctionsResponse.FulfillResult, uint96);
function isValidCallbackGasLimit(uint64 subscriptionId, uint32 callbackGasLimit) external view;
function getContractById(bytes32 id) external view returns (address);
function getProposedContractById(bytes32 id) external view returns (address);
function getProposedContractSet() external view returns (bytes32[] memory, address[] memory);
function proposeContractsUpdate(bytes32[] memory proposalSetIds, address[] memory proposalSetAddresses) external;
function updateContracts() external;
function pause() external;
function unpause() external;
}
文件 14 的 20:IFunctionsSubscriptions.sol
pragma solidity ^0.8.19;
import {FunctionsResponse} from "../libraries/FunctionsResponse.sol";
interface IFunctionsSubscriptions {
struct Subscription {
uint96 balance;
address owner;
uint96 blockedBalance;
address proposedOwner;
address[] consumers;
bytes32 flags;
}
struct Consumer {
bool allowed;
uint64 initiatedRequests;
uint64 completedRequests;
}
function getSubscription(uint64 subscriptionId) external view returns (Subscription memory);
function getSubscriptionsInRange(
uint64 subscriptionIdStart,
uint64 subscriptionIdEnd
) external view returns (Subscription[] memory);
function getConsumer(address client, uint64 subscriptionId) external view returns (Consumer memory);
function getTotalBalance() external view returns (uint96);
function getSubscriptionCount() external view returns (uint64);
function timeoutRequests(FunctionsResponse.Commitment[] calldata requestsToTimeoutByCommitment) external;
function oracleWithdraw(address recipient, uint96 amount) external;
function ownerCancelSubscription(uint64 subscriptionId) external;
function recoverFunds(address to) external;
function createSubscription() external returns (uint64);
function createSubscriptionWithConsumer(address consumer) external returns (uint64 subscriptionId);
function proposeSubscriptionOwnerTransfer(uint64 subscriptionId, address newOwner) external;
function acceptSubscriptionOwnerTransfer(uint64 subscriptionId) external;
function removeConsumer(uint64 subscriptionId, address consumer) external;
function addConsumer(uint64 subscriptionId, address consumer) external;
function cancelSubscription(uint64 subscriptionId, address to) external;
function pendingRequestExists(uint64 subscriptionId) external view returns (bool);
function setFlags(uint64 subscriptionId, bytes32 flags) external;
function getFlags(uint64 subscriptionId) external view returns (bytes32);
}
文件 15 的 20:IOwnable.sol
pragma solidity ^0.8.0;
interface IOwnable {
function owner() external returns (address);
function transferOwnership(address recipient) external;
function acceptOwnership() external;
}
文件 16 的 20:ITypeAndVersion.sol
pragma solidity ^0.8.0;
interface ITypeAndVersion {
function typeAndVersion() external pure returns (string memory);
}
文件 17 的 20:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 18 的 20:SafeCast.sol
pragma solidity ^0.8.0;
library SafeCast {
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
function toInt256(uint256 value) internal pure returns (int256) {
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}
文件 19 的 20:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
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);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 20 的 20:draft-IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
{
"compilationTarget": {
"src/v0.8/functions/dev/v1_X/FunctionsRouter.sol": "FunctionsRouter"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"runs": 1000000
},
"remappings": [
":@eth-optimism/=node_modules/@eth-optimism/",
":@openzeppelin/=node_modules/@openzeppelin/",
":@scroll-tech/=node_modules/@scroll-tech/",
":ds-test/=foundry-lib/forge-std/lib/ds-test/src/",
":forge-std/=foundry-lib/forge-std/src/",
":hardhat/=node_modules/hardhat/"
]
}
[{"inputs":[{"internalType":"address","name":"linkToken","type":"address"},{"components":[{"internalType":"uint16","name":"maxConsumersPerSubscription","type":"uint16"},{"internalType":"uint72","name":"adminFee","type":"uint72"},{"internalType":"bytes4","name":"handleOracleFulfillmentSelector","type":"bytes4"},{"internalType":"uint16","name":"gasForCallExactCheck","type":"uint16"},{"internalType":"uint32[]","name":"maxCallbackGasLimits","type":"uint32[]"},{"internalType":"uint16","name":"subscriptionDepositMinimumRequests","type":"uint16"},{"internalType":"uint72","name":"subscriptionDepositJuels","type":"uint72"}],"internalType":"struct FunctionsRouter.Config","name":"config","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CannotRemoveWithPendingRequests","type":"error"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"}],"name":"DuplicateRequestId","type":"error"},{"inputs":[],"name":"EmptyRequestData","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":[{"internalType":"uint96","name":"currentBalanceJuels","type":"uint96"}],"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":"OnlyCallableFromCoordinator","type":"error"},{"inputs":[],"name":"OnlyCallableFromLink","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":"TimeoutNotExceeded","type":"error"},{"inputs":[{"internalType":"uint16","name":"maximumConsumers","type":"uint16"}],"name":"TooManyConsumers","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint16","name":"maxConsumersPerSubscription","type":"uint16"},{"internalType":"uint72","name":"adminFee","type":"uint72"},{"internalType":"bytes4","name":"handleOracleFulfillmentSelector","type":"bytes4"},{"internalType":"uint16","name":"gasForCallExactCheck","type":"uint16"},{"internalType":"uint32[]","name":"maxCallbackGasLimits","type":"uint32[]"},{"internalType":"uint16","name":"subscriptionDepositMinimumRequests","type":"uint16"},{"internalType":"uint72","name":"subscriptionDepositJuels","type":"uint72"}],"indexed":false,"internalType":"struct FunctionsRouter.Config","name":"","type":"tuple"}],"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"}],"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":"enum FunctionsResponse.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":"enum FunctionsResponse.FulfillResult","name":"resultCode","type":"uint8"},{"indexed":false,"internalType":"bytes","name":"response","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"err","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"callbackReturnData","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":"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":"address","name":"consumer","type":"address"}],"name":"createSubscriptionWithConsumer","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":"costWithoutFulfillment","type":"uint96"},{"internalType":"address","name":"transmitter","type":"address"},{"components":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"address","name":"coordinator","type":"address"},{"internalType":"uint96","name":"estimatedTotalCostJuels","type":"uint96"},{"internalType":"address","name":"client","type":"address"},{"internalType":"uint64","name":"subscriptionId","type":"uint64"},{"internalType":"uint32","name":"callbackGasLimit","type":"uint32"},{"internalType":"uint72","name":"adminFee","type":"uint72"},{"internalType":"uint72","name":"donFee","type":"uint72"},{"internalType":"uint40","name":"gasOverheadBeforeCallback","type":"uint40"},{"internalType":"uint40","name":"gasOverheadAfterCallback","type":"uint40"},{"internalType":"uint32","name":"timeoutTimestamp","type":"uint32"}],"internalType":"struct FunctionsResponse.Commitment","name":"commitment","type":"tuple"}],"name":"fulfill","outputs":[{"internalType":"enum FunctionsResponse.FulfillResult","name":"resultCode","type":"uint8"},{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAdminFee","outputs":[{"internalType":"uint72","name":"","type":"uint72"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllowListId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConfig","outputs":[{"components":[{"internalType":"uint16","name":"maxConsumersPerSubscription","type":"uint16"},{"internalType":"uint72","name":"adminFee","type":"uint72"},{"internalType":"bytes4","name":"handleOracleFulfillmentSelector","type":"bytes4"},{"internalType":"uint16","name":"gasForCallExactCheck","type":"uint16"},{"internalType":"uint32[]","name":"maxCallbackGasLimits","type":"uint32[]"},{"internalType":"uint16","name":"subscriptionDepositMinimumRequests","type":"uint16"},{"internalType":"uint72","name":"subscriptionDepositJuels","type":"uint72"}],"internalType":"struct FunctionsRouter.Config","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"client","type":"address"},{"internalType":"uint64","name":"subscriptionId","type":"uint64"}],"name":"getConsumer","outputs":[{"components":[{"internalType":"bool","name":"allowed","type":"bool"},{"internalType":"uint64","name":"initiatedRequests","type":"uint64"},{"internalType":"uint64","name":"completedRequests","type":"uint64"}],"internalType":"struct IFunctionsSubscriptions.Consumer","name":"","type":"tuple"}],"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":"bytes32[]","name":"","type":"bytes32[]"},{"internalType":"address[]","name":"","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":"struct IFunctionsSubscriptions.Subscription","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSubscriptionCount","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"subscriptionIdStart","type":"uint64"},{"internalType":"uint64","name":"subscriptionIdEnd","type":"uint64"}],"name":"getSubscriptionsInRange","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":"struct IFunctionsSubscriptions.Subscription[]","name":"subscriptions","type":"tuple[]"}],"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":"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":"bytes32","name":"allowListId","type":"bytes32"}],"name":"setAllowListId","outputs":[],"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":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"address","name":"coordinator","type":"address"},{"internalType":"uint96","name":"estimatedTotalCostJuels","type":"uint96"},{"internalType":"address","name":"client","type":"address"},{"internalType":"uint64","name":"subscriptionId","type":"uint64"},{"internalType":"uint32","name":"callbackGasLimit","type":"uint32"},{"internalType":"uint72","name":"adminFee","type":"uint72"},{"internalType":"uint72","name":"donFee","type":"uint72"},{"internalType":"uint40","name":"gasOverheadBeforeCallback","type":"uint40"},{"internalType":"uint40","name":"gasOverheadAfterCallback","type":"uint40"},{"internalType":"uint32","name":"timeoutTimestamp","type":"uint32"}],"internalType":"struct FunctionsResponse.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":[{"components":[{"internalType":"uint16","name":"maxConsumersPerSubscription","type":"uint16"},{"internalType":"uint72","name":"adminFee","type":"uint72"},{"internalType":"bytes4","name":"handleOracleFulfillmentSelector","type":"bytes4"},{"internalType":"uint16","name":"gasForCallExactCheck","type":"uint16"},{"internalType":"uint32[]","name":"maxCallbackGasLimits","type":"uint32[]"},{"internalType":"uint16","name":"subscriptionDepositMinimumRequests","type":"uint16"},{"internalType":"uint72","name":"subscriptionDepositJuels","type":"uint72"}],"internalType":"struct FunctionsRouter.Config","name":"config","type":"tuple"}],"name":"updateConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateContracts","outputs":[],"stateMutability":"nonpayable","type":"function"}]