// SPDX-License-Identifier: MIT pragma solidity 0.8.6; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/proxy/Proxy.sol"; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; import "../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/Address.sol"; import "./KeeperRegistryBase2_0.sol"; import {AutomationRegistryExecutableInterface, UpkeepInfo, State, OnchainConfig, UpkeepFailureReason} from "../interfaces/v2_0/AutomationRegistryInterface2_0.sol"; import "../interfaces/MigratableKeeperRegistryInterface.sol"; import "../interfaces/MigratableKeeperRegistryInterfaceV2.sol"; import "../../shared/interfaces/IERC677Receiver.sol"; import {OCR2Abstract} from "../../shared/ocr2/OCR2Abstract.sol"; /** _. _|_ _ ._ _ _._|_o _ ._ o _ _ ._ _| _ __|_o._ (_||_||_(_)| | |(_| |_|(_)| | |_> (_)|_|| (_|(/__> |_|| |\/ / */ /** * @notice Registry for adding work for Chainlink Keepers to perform on client * contracts. Clients must support the Upkeep interface. */ contract KeeperRegistry2_0 is KeeperRegistryBase2_0, Proxy, OCR2Abstract, AutomationRegistryExecutableInterface, MigratableKeeperRegistryInterface, MigratableKeeperRegistryInterfaceV2, IERC677Receiver { using Address for address; using EnumerableSet for EnumerableSet.UintSet; // Immutable address of logic contract where some functionality is delegated to address private immutable i_keeperRegistryLogic; /** * @notice versions: * - KeeperRegistry 2.0.2: pass revert bytes as performData when target contract reverts * : fixes issue with arbitrum block number * : does an early return in case of stale report instead of revert * - KeeperRegistry 2.0.1: implements workaround for buggy migrate function in 1.X * - KeeperRegistry 2.0.0: implement OCR interface * - KeeperRegistry 1.3.0: split contract into Proxy and Logic * : account for Arbitrum and Optimism L1 gas fee * : allow users to configure upkeeps * - KeeperRegistry 1.2.0: allow funding within performUpkeep * : allow configurable registry maxPerformGas * : add function to let admin change upkeep gas limit * : add minUpkeepSpend requirement * : upgrade to solidity v0.8 * - KeeperRegistry 1.1.0: added flatFeeMicroLink * - KeeperRegistry 1.0.0: initial release */ string public constant override typeAndVersion = "KeeperRegistry 2.0.2"; /** * @inheritdoc MigratableKeeperRegistryInterface */ UpkeepFormat public constant override upkeepTranscoderVersion = UPKEEP_TRANSCODER_VERSION_BASE; /** * @inheritdoc MigratableKeeperRegistryInterfaceV2 */ uint8 public constant override upkeepVersion = UPKEEP_VERSION_BASE; /** * @param keeperRegistryLogic address of the logic contract */ constructor( KeeperRegistryBase2_0 keeperRegistryLogic ) KeeperRegistryBase2_0( keeperRegistryLogic.getMode(), keeperRegistryLogic.getLinkAddress(), keeperRegistryLogic.getLinkNativeFeedAddress(), keeperRegistryLogic.getFastGasFeedAddress() ) { i_keeperRegistryLogic = address(keeperRegistryLogic); } //////// // ACTIONS //////// /** * @dev This struct is used to maintain run time information about an upkeep in transmit function * @member upkeep the upkeep struct * @member earlyChecksPassed whether the upkeep passed early checks before perform * @member paymentParams the paymentParams for this upkeep * @member performSuccess whether the perform was successful * @member gasUsed gasUsed by this upkeep in perform */ struct UpkeepTransmitInfo { Upkeep upkeep; bool earlyChecksPassed; uint96 maxLinkPayment; bool performSuccess; uint256 gasUsed; uint256 gasOverhead; } /** * @inheritdoc OCR2Abstract */ function transmit( bytes32[3] calldata reportContext, bytes calldata rawReport, bytes32[] calldata rs, bytes32[] calldata ss, bytes32 rawVs ) external override { uint256 gasOverhead = gasleft(); HotVars memory hotVars = s_hotVars; if (hotVars.paused) revert RegistryPaused(); if (!s_transmitters[msg.sender].active) revert OnlyActiveTransmitters(); Report memory report = _decodeReport(rawReport); UpkeepTransmitInfo[] memory upkeepTransmitInfo = new UpkeepTransmitInfo[](report.upkeepIds.length); uint16 numUpkeepsPassedChecks; for (uint256 i = 0; i < report.upkeepIds.length; i++) { upkeepTransmitInfo[i].upkeep = s_upkeep[report.upkeepIds[i]]; upkeepTransmitInfo[i].maxLinkPayment = _getMaxLinkPayment( hotVars, upkeepTransmitInfo[i].upkeep.executeGas, uint32(report.wrappedPerformDatas[i].performData.length), report.fastGasWei, report.linkNative, true ); upkeepTransmitInfo[i].earlyChecksPassed = _prePerformChecks( report.upkeepIds[i], report.wrappedPerformDatas[i], upkeepTransmitInfo[i].upkeep, upkeepTransmitInfo[i].maxLinkPayment ); if (upkeepTransmitInfo[i].earlyChecksPassed) { numUpkeepsPassedChecks += 1; } } // No upkeeps to be performed in this report if (numUpkeepsPassedChecks == 0) { return; } // Verify signatures if (s_latestConfigDigest != reportContext[0]) revert ConfigDigestMismatch(); if (rs.length != hotVars.f + 1 || rs.length != ss.length) revert IncorrectNumberOfSignatures(); _verifyReportSignature(reportContext, rawReport, rs, ss, rawVs); // Actually perform upkeeps for (uint256 i = 0; i < report.upkeepIds.length; i++) { if (upkeepTransmitInfo[i].earlyChecksPassed) { // Check if this upkeep was already performed in this report if (s_upkeep[report.upkeepIds[i]].lastPerformBlockNumber == uint32(_blockNum())) { revert InvalidReport(); } // Actually perform the target upkeep (upkeepTransmitInfo[i].performSuccess, upkeepTransmitInfo[i].gasUsed) = _performUpkeep( upkeepTransmitInfo[i].upkeep, report.wrappedPerformDatas[i].performData ); // Deduct that gasUsed by upkeep from our running counter gasOverhead -= upkeepTransmitInfo[i].gasUsed; // Store last perform block number for upkeep s_upkeep[report.upkeepIds[i]].lastPerformBlockNumber = uint32(_blockNum()); } } // This is the overall gas overhead that will be split across performed upkeeps // Take upper bound of 16 gas per callData bytes, which is approximated to be reportLength // Rest of msg.data is accounted for in accounting overheads gasOverhead = (gasOverhead - gasleft() + 16 * rawReport.length) + ACCOUNTING_FIXED_GAS_OVERHEAD + (ACCOUNTING_PER_SIGNER_GAS_OVERHEAD * (hotVars.f + 1)); gasOverhead = gasOverhead / numUpkeepsPassedChecks + ACCOUNTING_PER_UPKEEP_GAS_OVERHEAD; uint96 totalReimbursement; uint96 totalPremium; { uint96 reimbursement; uint96 premium; for (uint256 i = 0; i < report.upkeepIds.length; i++) { if (upkeepTransmitInfo[i].earlyChecksPassed) { upkeepTransmitInfo[i].gasOverhead = _getCappedGasOverhead( gasOverhead, uint32(report.wrappedPerformDatas[i].performData.length), hotVars.f ); (reimbursement, premium) = _postPerformPayment( hotVars, report.upkeepIds[i], upkeepTransmitInfo[i], report.fastGasWei, report.linkNative, numUpkeepsPassedChecks ); totalPremium += premium; totalReimbursement += reimbursement; emit UpkeepPerformed( report.upkeepIds[i], upkeepTransmitInfo[i].performSuccess, report.wrappedPerformDatas[i].checkBlockNumber, upkeepTransmitInfo[i].gasUsed, upkeepTransmitInfo[i].gasOverhead, reimbursement + premium ); } } } // record payments s_transmitters[msg.sender].balance += totalReimbursement; s_hotVars.totalPremium += totalPremium; uint40 epochAndRound = uint40(uint256(reportContext[1])); uint32 epoch = uint32(epochAndRound >> 8); if (epoch > hotVars.latestEpoch) { s_hotVars.latestEpoch = epoch; } } /** * @notice simulates the upkeep with the perform data returned from * checkUpkeep * @param id identifier of the upkeep to execute the data with. * @param performData calldata parameter to be passed to the target upkeep. */ function simulatePerformUpkeep( uint256 id, bytes calldata performData ) external cannotExecute returns (bool success, uint256 gasUsed) { if (s_hotVars.paused) revert RegistryPaused(); Upkeep memory upkeep = s_upkeep[id]; return _performUpkeep(upkeep, performData); } /** * @notice uses LINK's transferAndCall to LINK and add funding to an upkeep * @dev safe to cast uint256 to uint96 as total LINK supply is under UINT96MAX * @param sender the account which transferred the funds * @param amount number of LINK transfer */ function onTokenTransfer(address sender, uint256 amount, bytes calldata data) external override { if (msg.sender != address(i_link)) revert OnlyCallableByLINKToken(); if (data.length != 32) revert InvalidDataLength(); uint256 id = abi.decode(data, (uint256)); if (s_upkeep[id].maxValidBlocknumber != UINT32_MAX) revert UpkeepCancelled(); s_upkeep[id].balance = s_upkeep[id].balance + uint96(amount); s_expectedLinkBalance = s_expectedLinkBalance + amount; emit FundsAdded(id, sender, uint96(amount)); } //////// // SETTERS //////// /** * @inheritdoc OCR2Abstract */ function setConfig( address[] memory signers, address[] memory transmitters, uint8 f, bytes memory onchainConfig, uint64 offchainConfigVersion, bytes memory offchainConfig ) external override onlyOwner { if (signers.length > MAX_NUM_ORACLES) revert TooManyOracles(); if (f == 0) revert IncorrectNumberOfFaultyOracles(); if (signers.length != transmitters.length || signers.length <= 3 * f) revert IncorrectNumberOfSigners(); // move all pooled payments out of the pool to each transmitter's balance uint96 totalPremium = s_hotVars.totalPremium; uint96 oldLength = uint96(s_transmittersList.length); for (uint256 i = 0; i < oldLength; i++) { _updateTransmitterBalanceFromPool(s_transmittersList[i], totalPremium, oldLength); } // remove any old signer/transmitter addresses address signerAddress; address transmitterAddress; for (uint256 i = 0; i < oldLength; i++) { signerAddress = s_signersList[i]; transmitterAddress = s_transmittersList[i]; delete s_signers[signerAddress]; // Do not delete the whole transmitter struct as it has balance information stored s_transmitters[transmitterAddress].active = false; } delete s_signersList; delete s_transmittersList; // add new signer/transmitter addresses { Transmitter memory transmitter; address temp; for (uint256 i = 0; i < signers.length; i++) { if (s_signers[signers[i]].active) revert RepeatedSigner(); s_signers[signers[i]] = Signer({active: true, index: uint8(i)}); temp = transmitters[i]; transmitter = s_transmitters[temp]; if (transmitter.active) revert RepeatedTransmitter(); transmitter.active = true; transmitter.index = uint8(i); transmitter.lastCollected = totalPremium; s_transmitters[temp] = transmitter; } } s_signersList = signers; s_transmittersList = transmitters; // Set the onchain config OnchainConfig memory onchainConfigStruct = abi.decode(onchainConfig, (OnchainConfig)); if (onchainConfigStruct.maxPerformGas < s_storage.maxPerformGas) revert GasLimitCanOnlyIncrease(); if (onchainConfigStruct.maxCheckDataSize < s_storage.maxCheckDataSize) revert MaxCheckDataSizeCanOnlyIncrease(); if (onchainConfigStruct.maxPerformDataSize < s_storage.maxPerformDataSize) revert MaxPerformDataSizeCanOnlyIncrease(); s_hotVars = HotVars({ f: f, paymentPremiumPPB: onchainConfigStruct.paymentPremiumPPB, flatFeeMicroLink: onchainConfigStruct.flatFeeMicroLink, stalenessSeconds: onchainConfigStruct.stalenessSeconds, gasCeilingMultiplier: onchainConfigStruct.gasCeilingMultiplier, paused: false, reentrancyGuard: false, totalPremium: totalPremium, latestEpoch: 0 }); s_storage = Storage({ checkGasLimit: onchainConfigStruct.checkGasLimit, minUpkeepSpend: onchainConfigStruct.minUpkeepSpend, maxPerformGas: onchainConfigStruct.maxPerformGas, transcoder: onchainConfigStruct.transcoder, registrar: onchainConfigStruct.registrar, maxCheckDataSize: onchainConfigStruct.maxCheckDataSize, maxPerformDataSize: onchainConfigStruct.maxPerformDataSize, nonce: s_storage.nonce, configCount: s_storage.configCount, latestConfigBlockNumber: s_storage.latestConfigBlockNumber, ownerLinkBalance: s_storage.ownerLinkBalance }); s_fallbackGasPrice = onchainConfigStruct.fallbackGasPrice; s_fallbackLinkPrice = onchainConfigStruct.fallbackLinkPrice; uint32 previousConfigBlockNumber = s_storage.latestConfigBlockNumber; s_storage.latestConfigBlockNumber = uint32(_blockNum()); s_storage.configCount += 1; s_latestConfigDigest = _configDigestFromConfigData( block.chainid, address(this), s_storage.configCount, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig ); emit ConfigSet( previousConfigBlockNumber, s_latestConfigDigest, s_storage.configCount, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig ); } //////// // GETTERS //////// /** * @notice read all of the details about an upkeep */ function getUpkeep(uint256 id) external view override returns (UpkeepInfo memory upkeepInfo) { Upkeep memory reg = s_upkeep[id]; upkeepInfo = UpkeepInfo({ target: reg.target, executeGas: reg.executeGas, checkData: s_checkData[id], balance: reg.balance, admin: s_upkeepAdmin[id], maxValidBlocknumber: reg.maxValidBlocknumber, lastPerformBlockNumber: reg.lastPerformBlockNumber, amountSpent: reg.amountSpent, paused: reg.paused, offchainConfig: s_upkeepOffchainConfig[id] }); return upkeepInfo; } /** * @notice retrieve active upkeep IDs. Active upkeep is defined as an upkeep which is not paused and not canceled. * @param startIndex starting index in list * @param maxCount max count to retrieve (0 = unlimited) * @dev the order of IDs in the list is **not guaranteed**, therefore, if making successive calls, one * should consider keeping the blockheight constant to ensure a holistic picture of the contract state */ function getActiveUpkeepIDs(uint256 startIndex, uint256 maxCount) external view override returns (uint256[] memory) { uint256 maxIdx = s_upkeepIDs.length(); if (startIndex >= maxIdx) revert IndexOutOfRange(); if (maxCount == 0) { maxCount = maxIdx - startIndex; } uint256[] memory ids = new uint256[](maxCount); for (uint256 idx = 0; idx < maxCount; idx++) { ids[idx] = s_upkeepIDs.at(startIndex + idx); } return ids; } /** * @notice read the current info about any transmitter address */ function getTransmitterInfo( address query ) external view override returns (bool active, uint8 index, uint96 balance, uint96 lastCollected, address payee) { Transmitter memory transmitter = s_transmitters[query]; uint96 totalDifference = s_hotVars.totalPremium - transmitter.lastCollected; uint96 pooledShare = totalDifference / uint96(s_transmittersList.length); return ( transmitter.active, transmitter.index, (transmitter.balance + pooledShare), transmitter.lastCollected, s_transmitterPayees[query] ); } /** * @notice read the current info about any signer address */ function getSignerInfo(address query) external view returns (bool active, uint8 index) { Signer memory signer = s_signers[query]; return (signer.active, signer.index); } /** * @notice read the current state of the registry */ function getState() external view override returns ( State memory state, OnchainConfig memory config, address[] memory signers, address[] memory transmitters, uint8 f ) { state = State({ nonce: s_storage.nonce, ownerLinkBalance: s_storage.ownerLinkBalance, expectedLinkBalance: s_expectedLinkBalance, totalPremium: s_hotVars.totalPremium, numUpkeeps: s_upkeepIDs.length(), configCount: s_storage.configCount, latestConfigBlockNumber: s_storage.latestConfigBlockNumber, latestConfigDigest: s_latestConfigDigest, latestEpoch: s_hotVars.latestEpoch, paused: s_hotVars.paused }); config = OnchainConfig({ paymentPremiumPPB: s_hotVars.paymentPremiumPPB, flatFeeMicroLink: s_hotVars.flatFeeMicroLink, checkGasLimit: s_storage.checkGasLimit, stalenessSeconds: s_hotVars.stalenessSeconds, gasCeilingMultiplier: s_hotVars.gasCeilingMultiplier, minUpkeepSpend: s_storage.minUpkeepSpend, maxPerformGas: s_storage.maxPerformGas, maxCheckDataSize: s_storage.maxCheckDataSize, maxPerformDataSize: s_storage.maxPerformDataSize, fallbackGasPrice: s_fallbackGasPrice, fallbackLinkPrice: s_fallbackLinkPrice, transcoder: s_storage.transcoder, registrar: s_storage.registrar }); return (state, config, s_signersList, s_transmittersList, s_hotVars.f); } /** * @notice calculates the minimum balance required for an upkeep to remain eligible * @param id the upkeep id to calculate minimum balance for */ function getMinBalanceForUpkeep(uint256 id) external view returns (uint96 minBalance) { return getMaxPaymentForGas(s_upkeep[id].executeGas); } /** * @notice calculates the maximum payment for a given gas limit * @param gasLimit the gas to calculate payment for */ function getMaxPaymentForGas(uint32 gasLimit) public view returns (uint96 maxPayment) { HotVars memory hotVars = s_hotVars; (uint256 fastGasWei, uint256 linkNative) = _getFeedData(hotVars); return _getMaxLinkPayment(hotVars, gasLimit, s_storage.maxPerformDataSize, fastGasWei, linkNative, false); } /** * @notice retrieves the migration permission for a peer registry */ function getPeerRegistryMigrationPermission(address peer) external view returns (MigrationPermission) { return s_peerRegistryMigrationPermission[peer]; } /** * @notice retrieves the address of the logic address */ function getKeeperRegistryLogicAddress() external view returns (address) { return i_keeperRegistryLogic; } /** * @inheritdoc OCR2Abstract */ function latestConfigDetails() external view override returns (uint32 configCount, uint32 blockNumber, bytes32 configDigest) { return (s_storage.configCount, s_storage.latestConfigBlockNumber, s_latestConfigDigest); } /** * @inheritdoc OCR2Abstract */ function latestConfigDigestAndEpoch() external view override returns (bool scanLogs, bytes32 configDigest, uint32 epoch) { return (false, s_latestConfigDigest, s_hotVars.latestEpoch); } //////// // INTERNAL FUNCTIONS //////// /** * @dev This is the address to which proxy functions are delegated to */ function _implementation() internal view override returns (address) { return i_keeperRegistryLogic; } /** * @dev calls target address with exactly gasAmount gas and data as calldata * or reverts if at least gasAmount gas is not available */ function _callWithExactGas(uint256 gasAmount, address target, bytes memory data) private returns (bool success) { assembly { let g := gas() // Compute g -= PERFORM_GAS_CUSHION and check for underflow if lt(g, PERFORM_GAS_CUSHION) { revert(0, 0) } g := sub(g, PERFORM_GAS_CUSHION) // if g - g//64 <= gasAmount, revert // (we subtract g//64 because of EIP-150) if iszero(gt(sub(g, div(g, 64)), gasAmount)) { revert(0, 0) } // solidity calls check that a contract actually exists at the destination, so we do the same if iszero(extcodesize(target)) { revert(0, 0) } // call and return whether we succeeded. ignore return data success := call(gasAmount, target, 0, add(data, 0x20), mload(data), 0, 0) } return success; } /** * @dev _decodeReport decodes a serialized report into a Report struct */ function _decodeReport(bytes memory rawReport) internal pure returns (Report memory) { ( uint256 fastGasWei, uint256 linkNative, uint256[] memory upkeepIds, PerformDataWrapper[] memory wrappedPerformDatas ) = abi.decode(rawReport, (uint256, uint256, uint256[], PerformDataWrapper[])); if (upkeepIds.length != wrappedPerformDatas.length) revert InvalidReport(); return Report({ fastGasWei: fastGasWei, linkNative: linkNative, upkeepIds: upkeepIds, wrappedPerformDatas: wrappedPerformDatas }); } /** * @dev Does some early sanity checks before actually performing an upkeep */ function _prePerformChecks( uint256 upkeepId, PerformDataWrapper memory wrappedPerformData, Upkeep memory upkeep, uint96 maxLinkPayment ) internal returns (bool) { if (wrappedPerformData.checkBlockNumber < upkeep.lastPerformBlockNumber) { // Can happen when another report performed this upkeep after this report was generated emit StaleUpkeepReport(upkeepId); return false; } if (_blockHash(wrappedPerformData.checkBlockNumber) != wrappedPerformData.checkBlockhash) { // Can happen when the block on which report was generated got reorged // We will also revert if checkBlockNumber is older than 256 blocks. In this case we rely on a new transmission // with the latest checkBlockNumber emit ReorgedUpkeepReport(upkeepId); return false; } if (upkeep.maxValidBlocknumber <= _blockNum()) { // Can happen when an upkeep got cancelled after report was generated. // However we have a CANCELLATION_DELAY of 50 blocks so shouldn't happen in practice emit CancelledUpkeepReport(upkeepId); return false; } if (upkeep.balance < maxLinkPayment) { // Can happen due to flucutations in gas / link prices emit InsufficientFundsUpkeepReport(upkeepId); return false; } return true; } /** * @dev Verify signatures attached to report */ function _verifyReportSignature( bytes32[3] calldata reportContext, bytes calldata report, bytes32[] calldata rs, bytes32[] calldata ss, bytes32 rawVs ) internal view { bytes32 h = keccak256(abi.encode(keccak256(report), reportContext)); // i-th byte counts number of sigs made by i-th signer uint256 signedCount = 0; Signer memory signer; address signerAddress; for (uint256 i = 0; i < rs.length; i++) { signerAddress = ecrecover(h, uint8(rawVs[i]) + 27, rs[i], ss[i]); signer = s_signers[signerAddress]; if (!signer.active) revert OnlyActiveSigners(); unchecked { signedCount += 1 << (8 * signer.index); } } if (signedCount & ORACLE_MASK != signedCount) revert DuplicateSigners(); } /** * @dev calls the Upkeep target with the performData param passed in by the * transmitter and the exact gas required by the Upkeep */ function _performUpkeep( Upkeep memory upkeep, bytes memory performData ) private nonReentrant returns (bool success, uint256 gasUsed) { gasUsed = gasleft(); bytes memory callData = abi.encodeWithSelector(PERFORM_SELECTOR, performData); success = _callWithExactGas(upkeep.executeGas, upkeep.target, callData); gasUsed = gasUsed - gasleft(); return (success, gasUsed); } /** * @dev does postPerform payment processing for an upkeep. Deducts upkeep's balance and increases * amount spent. */ function _postPerformPayment( HotVars memory hotVars, uint256 upkeepId, UpkeepTransmitInfo memory upkeepTransmitInfo, uint256 fastGasWei, uint256 linkNative, uint16 numBatchedUpkeeps ) internal returns (uint96 gasReimbursement, uint96 premium) { (gasReimbursement, premium) = _calculatePaymentAmount( hotVars, upkeepTransmitInfo.gasUsed, upkeepTransmitInfo.gasOverhead, fastGasWei, linkNative, numBatchedUpkeeps, true ); uint96 payment = gasReimbursement + premium; s_upkeep[upkeepId].balance -= payment; s_upkeep[upkeepId].amountSpent += payment; return (gasReimbursement, premium); } /** * @dev Caps the gas overhead by the constant overhead used within initial payment checks in order to * prevent a revert in payment processing. */ function _getCappedGasOverhead( uint256 calculatedGasOverhead, uint32 performDataLength, uint8 f ) private pure returns (uint256 cappedGasOverhead) { cappedGasOverhead = _getMaxGasOverhead(performDataLength, f); if (calculatedGasOverhead < cappedGasOverhead) { return calculatedGasOverhead; } return cappedGasOverhead; } //////// // PROXY FUNCTIONS - EXECUTED THROUGH FALLBACK //////// /** * @notice adds a new upkeep * @param target address to perform upkeep on * @param gasLimit amount of gas to provide the target contract when * performing upkeep * @param admin address to cancel upkeep and withdraw remaining funds * @param checkData data passed to the contract when checking for upkeep */ function registerUpkeep( address target, uint32 gasLimit, address admin, bytes calldata checkData, bytes calldata offchainConfig ) external override returns (uint256 id) { // Executed through logic contract _fallback(); } /** * @notice simulated by keepers via eth_call to see if the upkeep needs to be * performed. It returns the success status / failure reason along with the perform data payload. * @param id identifier of the upkeep to check */ function checkUpkeep( uint256 id ) external override cannotExecute returns ( bool upkeepNeeded, bytes memory performData, UpkeepFailureReason upkeepFailureReason, uint256 gasUsed, uint256 fastGasWei, uint256 linkNative ) { // Executed through logic contract _fallback(); } /** * @notice prevent an upkeep from being performed in the future * @param id upkeep to be canceled */ function cancelUpkeep(uint256 id) external override { // Executed through logic contract _fallback(); } /** * @notice pause an upkeep * @param id upkeep to be paused */ function pauseUpkeep(uint256 id) external override { // Executed through logic contract _fallback(); } /** * @notice unpause an upkeep * @param id upkeep to be resumed */ function unpauseUpkeep(uint256 id) external override { // Executed through logic contract _fallback(); } /** * @notice update the check data of an upkeep * @param id the id of the upkeep whose check data needs to be updated * @param newCheckData the new check data */ function updateCheckData(uint256 id, bytes calldata newCheckData) external override { // Executed through logic contract _fallback(); } /** * @notice adds LINK funding for an upkeep by transferring from the sender's * LINK balance * @param id upkeep to fund * @param amount number of LINK to transfer */ function addFunds(uint256 id, uint96 amount) external override { // Executed through logic contract _fallback(); } /** * @notice removes funding from a canceled upkeep * @param id upkeep to withdraw funds from * @param to destination address for sending remaining funds */ function withdrawFunds(uint256 id, address to) external { // Executed through logic contract // Restricted to nonRentrant in logic contract as this is not callable from a user's performUpkeep _fallback(); } /** * @notice allows the admin of an upkeep to modify gas limit * @param id upkeep to be change the gas limit for * @param gasLimit new gas limit for the upkeep */ function setUpkeepGasLimit(uint256 id, uint32 gasLimit) external override { // Executed through logic contract _fallback(); } /** * @notice allows the admin of an upkeep to modify the offchain config * @param id upkeep to be change the gas limit for * @param config instructs oracles of offchain config preferences */ function setUpkeepOffchainConfig(uint256 id, bytes calldata config) external override { // Executed through logic contract _fallback(); } /** * @notice withdraws a transmitter's payment, callable only by the transmitter's payee * @param from transmitter address * @param to address to send the payment to */ function withdrawPayment(address from, address to) external { // Executed through logic contract _fallback(); } /** * @notice proposes the safe transfer of a transmitter's payee to another address * @param transmitter address of the transmitter to transfer payee role * @param proposed address to nominate for next payeeship */ function transferPayeeship(address transmitter, address proposed) external { // Executed through logic contract _fallback(); } /** * @notice accepts the safe transfer of payee role for a transmitter * @param transmitter address to accept the payee role for */ function acceptPayeeship(address transmitter) external { // Executed through logic contract _fallback(); } /** * @notice proposes the safe transfer of an upkeep's admin role to another address * @param id the upkeep id to transfer admin * @param proposed address to nominate for the new upkeep admin */ function transferUpkeepAdmin(uint256 id, address proposed) external override { // Executed through logic contract _fallback(); } /** * @notice accepts the safe transfer of admin role for an upkeep * @param id the upkeep id */ function acceptUpkeepAdmin(uint256 id) external override { // Executed through logic contract _fallback(); } /** * @inheritdoc MigratableKeeperRegistryInterface */ function migrateUpkeeps( uint256[] calldata ids, address destination ) external override(MigratableKeeperRegistryInterface, MigratableKeeperRegistryInterfaceV2) { // Executed through logic contract _fallback(); } /** * @inheritdoc MigratableKeeperRegistryInterface */ function receiveUpkeeps( bytes calldata encodedUpkeeps ) external override(MigratableKeeperRegistryInterface, MigratableKeeperRegistryInterfaceV2) { // Executed through logic contract _fallback(); } //////// // OWNER RESTRICTED FUNCTIONS //////// /** * @notice recovers LINK funds improperly transferred to the registry * @dev In principle this function’s execution cost could exceed block * gas limit. However, in our anticipated deployment, the number of upkeeps and * transmitters will be low enough to avoid this problem. */ function recoverFunds() external { // Executed through logic contract // Restricted to onlyOwner in logic contract _fallback(); } /** * @notice withdraws LINK funds collected through cancellation fees */ function withdrawOwnerFunds() external { // Executed through logic contract // Restricted to onlyOwner in logic contract _fallback(); } /** * @notice update the list of payees corresponding to the transmitters * @param payees addresses corresponding to transmitters who are allowed to * move payments which have been accrued */ function setPayees(address[] calldata payees) external { // Executed through logic contract // Restricted to onlyOwner in logic contract _fallback(); } /** * @notice signals to transmitters that they should not perform upkeeps until the * contract has been unpaused */ function pause() external { // Executed through logic contract // Restricted to onlyOwner in logic contract _fallback(); } /** * @notice signals to transmitters that they can perform upkeeps once again after * having been paused */ function unpause() external { // Executed through logic contract // Restricted to onlyOwner in logic contract _fallback(); } /** * @notice sets the peer registry migration permission */ function setPeerRegistryMigrationPermission(address peer, MigrationPermission permission) external { // Executed through logic contract // Restricted to onlyOwner in logic contract _fallback(); } }