// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "./PriceFeedKeeper.sol"; /** * @title ChainlinkKeeperCompatible * @notice Chainlink Keepers compatible wrapper for PriceFeedKeeper * @dev Implements AutomationCompatibleInterface for Chainlink Automation * * Note: This interface matches Chainlink's AutomationCompatibleInterface. * If Chainlink contracts are installed, you can import from: * chainlink/contracts/src/v0.8/interfaces/AutomationCompatibleInterface.sol */ interface AutomationCompatibleInterface { function checkUpkeep(bytes calldata checkData) external view returns (bool upkeepNeeded, bytes memory performData); function performUpkeep(bytes calldata performData) external; } contract ChainlinkKeeperCompatible is AutomationCompatibleInterface { PriceFeedKeeper public immutable keeper; constructor(address keeperAddress) { keeper = PriceFeedKeeper(keeperAddress); } /** * @notice Chainlink checkUpkeep function * @param checkData Encoded data (unused for our keeper) * @return upkeepNeeded True if upkeep is needed * @return performData Encoded data for performUpkeep */ function checkUpkeep(bytes calldata checkData) external view override returns (bool upkeepNeeded, bytes memory performData) { (bool needsUpdate, address[] memory assets) = keeper.checkUpkeep(); if (needsUpdate && assets.length > 0) { upkeepNeeded = true; performData = abi.encode(assets); } else { upkeepNeeded = false; performData = ""; } // Use checkData if provided (for custom filtering) if (checkData.length > 0) { // Custom logic can be added here } } /** * @notice Chainlink performUpkeep function * @param performData Encoded data from checkUpkeep */ function performUpkeep(bytes calldata performData) external override { if (performData.length > 0) { address[] memory assets = abi.decode(performData, (address[])); keeper.updateAssets(assets); } else { keeper.performUpkeep(); } } }