Skip to content

Commit

Permalink
feat: add mocks
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo Maldonado <[email protected]>
  • Loading branch information
md0x committed Oct 27, 2023
1 parent f9a7564 commit dd9216d
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 38 deletions.
32 changes: 25 additions & 7 deletions script/HoneyPot.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,52 @@ pragma solidity ^0.8.0;
import "forge-std/console2.sol";
import "forge-std/Script.sol";

import {ChronicleMedianSourceMock} from "../src/mock/ChronicleMedianSourceMock.sol";
import {IMedian} from "oev-contracts/interfaces/chronicle/IMedian.sol";
import {HoneyPotOEVShare} from "../src/HoneyPotOEVShare.sol";
import {HoneyPot} from "../src/HoneyPot.sol";
import {HoneyPotDAO} from "../src/HoneyPotDAO.sol";
import {IAggregatorV3Source} from "oev-contracts/interfaces/chainlink/IAggregatorV3Source.sol";

contract HoneyPotDeploymentScript is Script {
HoneyPotOEVShare oevShare;
HoneyPot honeyPot;
HoneyPotDAO honeyPotDAO;
ChronicleMedianSourceMock chronicleMock;

function run() external {
// Get deployment parameters from environment variables or use defaults.

vm.startBroadcast();

address chainlink = 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419;
address chronicle = 0x64DE91F5A373Cd4c28de3600cB34C7C6cE410C85;
address pyth = 0x4305FB66699C3B2702D4d05CF36551390A4c69C6;
bytes32 pythPriceId = 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace;
address chainlink = vm.envOr(
"CHAINLINK_SOURCE",
0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
);
address pyth = vm.envOr(
"PYTH_SOURCE",
0x4305FB66699C3B2702D4d05CF36551390A4c69C6
);

bytes32 defaultId = 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace;
bytes32 pythPriceId = vm.envOr("PYTH_PRICE_ID", bytes32(0));
if (pythPriceId == bytes32(0)) {
pythPriceId = defaultId;
}

// Create mock ChronicleMedianSource and set the latest source data.
chronicleMock = new ChronicleMedianSourceMock();

oevShare = new HoneyPotOEVShare(
chainlink,
chronicle,
address(chronicleMock),
pyth,
pythPriceId,
8
);

honeyPot = new HoneyPot(IAggregatorV3Source(address(oevShare)));

honeyPotDAO = new HoneyPotDAO();

vm.stopBroadcast();
}
}
21 changes: 0 additions & 21 deletions src/mock/ChronicleMedianSourceAdapterMock.sol

This file was deleted.

29 changes: 29 additions & 0 deletions src/mock/ChronicleMedianSourceMock.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.17;

import {IMedian} from "oev-contracts/interfaces/chronicle/IMedian.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

contract ChronicleMedianSourceMock is IMedian, Ownable {
uint256 public value;
uint32 public ageValue;

function age() external view returns (uint32) {
return ageValue;
}

function read() external view returns (uint256) {
return value;
}

function peek() external view returns (uint256, bool) {
return (value, true);
}

function setLatestSourceData(uint256 _value, uint32 _age) public onlyOwner {
value = _value;
ageValue = _age;
}

function kiss(address) external override {}
}
80 changes: 70 additions & 10 deletions test/HoneyPot.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,20 @@ import {IPyth} from "oev-contracts/interfaces/pyth/IPyth.sol";
import {HoneyPotOEVShare} from "../src/HoneyPotOEVShare.sol";
import {HoneyPot} from "../src/HoneyPot.sol";
import {HoneyPotDAO} from "../src/HoneyPotDAO.sol";
import {ChronicleMedianSourceAdapterMock} from "../src/mock/ChronicleMedianSourceAdapterMock.sol";
import {ChronicleMedianSourceMock} from "../src/mock/ChronicleMedianSourceMock.sol";

contract HoneyPotTest is CommonTest {
event ReceivedEther(address sender, uint256 amount);
event DrainedEther(address to, uint256 amount);

IAggregatorV3Source chainlink = IAggregatorV3Source(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);
IAggregatorV3Source chainlink =
IAggregatorV3Source(0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419);
IMedian chronicle = IMedian(0x64DE91F5A373Cd4c28de3600cB34C7C6cE410C85);
IPyth pyth = IPyth(0x4305FB66699C3B2702D4d05CF36551390A4c69C6);
bytes32 pythPriceId = 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace;
bytes32 pythPriceId =
0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace;

ChronicleMedianSourceAdapterMock chronicleMock = new ChronicleMedianSourceAdapterMock();
ChronicleMedianSourceMock chronicleMock;

HoneyPotOEVShare oevShare;
HoneyPot honeyPot;
Expand All @@ -43,6 +45,7 @@ contract HoneyPotTest is CommonTest {
honeyPotDAO = new HoneyPotDAO();
_whitelistOnChronicle();
oevShare.setUnlocker(address(this), true);
chronicleMock = new ChronicleMedianSourceMock();
}

receive() external payable {}
Expand All @@ -55,8 +58,13 @@ contract HoneyPotTest is CommonTest {
}

function mockChainlinkPriceChange() public {
(uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) =
chainlink.latestRoundData();
(
uint80 roundId,
int256 answer,
uint256 startedAt,
uint256 updatedAt,
uint80 answeredInRound
) = chainlink.latestRoundData();
vm.mockCall(
address(chainlink),
abi.encodeWithSelector(chainlink.latestRoundData.selector),
Expand All @@ -82,7 +90,9 @@ contract HoneyPotTest is CommonTest {

// Reset HoneyPot for the caller
honeyPot.resetPot();
(, uint256 testhoneyPotBalanceReset) = honeyPot.honeyPots(address(this));
(, uint256 testhoneyPotBalanceReset) = honeyPot.honeyPots(
address(this)
);
assertTrue(testhoneyPotBalanceReset == 0);
assertTrue(address(this).balance == balanceBefore);
}
Expand All @@ -95,7 +105,7 @@ contract HoneyPotTest is CommonTest {

vm.prank(liquidator);
vm.expectRevert("Liquidation price reached for this user");
honeyPot.emptyHoneyPot(address(this)); // emptyHoneyPot now requires the creator's address
honeyPot.emptyHoneyPot(address(this));

// Simulate price change
mockChainlinkPriceChange();
Expand All @@ -106,11 +116,13 @@ contract HoneyPotTest is CommonTest {
uint256 liquidatorBalanceBefore = liquidator.balance;

vm.prank(liquidator);
honeyPot.emptyHoneyPot(address(this)); // emptyHoneyPot now requires the creator's address
honeyPot.emptyHoneyPot(address(this));

uint256 liquidatorBalanceAfter = liquidator.balance;

assertTrue(liquidatorBalanceAfter == liquidatorBalanceBefore + honeyPotBalance);
assertTrue(
liquidatorBalanceAfter == liquidatorBalanceBefore + honeyPotBalance
);

// Create HoneyPot can be called again
honeyPot.createHoneyPot{value: honeyPotBalance}();
Expand All @@ -127,4 +139,52 @@ contract HoneyPotTest is CommonTest {
emit DrainedEther(address(this), 1 ether);
honeyPotDAO.drain();
}

function testChronicleMock() public {
uint32 age = chronicle.age();
uint256 read = chronicle.read();
chronicleMock.setLatestSourceData(read, age);

HoneyPotOEVShare oevShare2 = new HoneyPotOEVShare(
address(chainlink),
address(chronicleMock),
address(pyth),
pythPriceId,
8
);
oevShare2.setUnlocker(address(this), true);

HoneyPot honeyPot2 = new HoneyPot(
IAggregatorV3Source(address(oevShare2))
);

// Create HoneyPot for the caller
honeyPot2.createHoneyPot{value: honeyPotBalance}();
(, uint256 testhoneyPotBalance) = honeyPot2.honeyPots(address(this));
assertTrue(testhoneyPotBalance == honeyPotBalance);

vm.prank(liquidator);
vm.expectRevert("Liquidation price reached for this user");
honeyPot2.emptyHoneyPot(address(this));

// Simulate price change
chronicleMock.setLatestSourceData(
(read * 103) / 100,
uint32(block.timestamp - 1)
);

// Unlock the latest value
oevShare2.unlockLatestValue();

uint256 liquidatorBalanceBefore = liquidator.balance;

vm.prank(liquidator);
honeyPot2.emptyHoneyPot(address(this));

uint256 liquidatorBalanceAfter = liquidator.balance;

assertTrue(
liquidatorBalanceAfter == liquidatorBalanceBefore + honeyPotBalance
);
}
}

0 comments on commit dd9216d

Please sign in to comment.