// SPDX-License-Identifier: MIT pragma solidity ^0.8.24; import {Test} from "forge-std/Test.sol"; import {PluginOracleAdapter} from "../src/PluginOracleAdapter.sol"; import {PriceSnapshotUpkeep} from "../src/automation/PriceSnapshotUpkeep.sol"; import {Owned} from "../src/utils/Owned.sol"; import {IPluginFeed} from "../src/interfaces/IPluginFeed.sol"; import {MockPluginFeed} from "./mocks/Mocks.sol"; contract PriceSnapshotUpkeepTest is Test { MockPluginFeed feed; PriceSnapshotUpkeep upkeep; address fwd = address(0xF00D); function setUp() public { vm.warp(1_000_000); feed = new MockPluginFeed(16); feed.set(2e16, block.timestamp); PluginOracleAdapter a = new PluginOracleAdapter(IPluginFeed(address(feed)), 1 hours, 0, 0); upkeep = new PriceSnapshotUpkeep(a, 15 minutes, address(this)); upkeep.setForwarder(fwd); } function test_CheckThenPerform() public { (bool needed, bytes memory data) = upkeep.checkUpkeep(""); assertTrue(needed); vm.prank(fwd); upkeep.performUpkeep(data); assertEq(upkeep.lastPrice(), 2e16); assertEq(upkeep.runs(), 1); (needed,) = upkeep.checkUpkeep(""); assertFalse(needed); vm.prank(fwd); // forwarder spamming is still safe: condition re-checked vm.expectRevert(PriceSnapshotUpkeep.NotNeeded.selector); upkeep.performUpkeep(""); } function test_OnlyForwarder() public { vm.expectRevert(abi.encodeWithSelector(PriceSnapshotUpkeep.NotForwarder.selector, address(this))); upkeep.performUpkeep(""); upkeep.setForwarder(address(0)); // unset => nobody vm.prank(address(0)); vm.expectRevert(); upkeep.performUpkeep(""); } function test_OnlyOwnerSetsForwarder() public { vm.prank(address(0xBAD)); vm.expectRevert(Owned.NotOwner.selector); upkeep.setForwarder(address(0xBAD)); } function test_IntervalElapses() public { vm.prank(fwd); upkeep.performUpkeep(""); vm.warp(block.timestamp + 15 minutes); feed.set(3e16, block.timestamp); vm.prank(fwd); upkeep.performUpkeep(""); assertEq(upkeep.lastPrice(), 3e16); assertEq(upkeep.runs(), 2); } function test_PerformRevertsOnStaleFeed() public { vm.warp(block.timestamp + 2 hours); vm.prank(fwd); vm.expectRevert(); upkeep.performUpkeep(""); } }