// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "./PriceFeedKeeper.sol"; /** * @title GelatoKeeperCompatible * @notice Gelato Network compatible keeper for PriceFeedKeeper * @dev Implements Gelato's task execution pattern */ contract GelatoKeeperCompatible { PriceFeedKeeper public immutable keeper; address public immutable gelato; event TaskExecuted(address indexed executor, address[] assets, uint256 timestamp); constructor(address keeperAddress, address gelato_) { keeper = PriceFeedKeeper(keeperAddress); gelato = gelato_; } /** * @notice Gelato task execution function * @dev Called by Gelato executors */ function executeTask() external { require(msg.sender == gelato, "GelatoKeeperCompatible: only Gelato"); (bool needsUpdate, address[] memory assets) = keeper.checkUpkeep(); if (needsUpdate && assets.length > 0) { keeper.updateAssets(assets); emit TaskExecuted(msg.sender, assets, block.timestamp); } } /** * @notice Check if task can be executed * @return canExec True if task can be executed * @return execData Encoded execution data */ function canExec() external view returns (bool canExec, bytes memory execData) { (bool needsUpdate, address[] memory assets) = keeper.checkUpkeep(); if (needsUpdate && assets.length > 0) { canExec = true; execData = abi.encodeWithSelector(this.executeTask.selector); } else { canExec = false; execData = ""; } } }