Skip to content

Commit

Permalink
mocks: add chainlink library and forge fmt
Browse files Browse the repository at this point in the history
  • Loading branch information
arbaz-immunefi committed Feb 6, 2024
1 parent 2370f5d commit 873624e
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 38 deletions.
10 changes: 6 additions & 4 deletions src/log/Log.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ abstract contract Log {
}

// Enum defining different phases for logging
enum LogPhase {
// Default phase
enum LogPhase
// Default phase
{
DEFAULT,
// Log messages from the "Initiate Attack" phase
INITIALIZE_ATTACK,
Expand All @@ -34,8 +35,9 @@ abstract contract Log {
}

// Enum defining different types of logs
enum LogType {
// Log everything
enum LogType
// Log everything
{
ALL,
// Log messages from the "Initiate Attack" phase
INITIALIZE_ATTACK,
Expand Down
16 changes: 12 additions & 4 deletions src/oracle/examples/MockOracleExample.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ pragma solidity ^0.8.0;

import "forge-std/console.sol";

import "../../tokens/Tokens.sol";

import "../lib/MockPyth.sol";
import "../lib/MockChainLink.sol";

Expand All @@ -10,20 +12,26 @@ contract MockOracleExample {
bytes32 pid = 0x2f95862b045670cd22bee3114c39763a4a08beeb663b145d283c31d7d1101c4f; // BNB/USD

function initiateAttack() external {
MockPyth.mockOracleData(pid, 1);
//1. PYTH ORACLE
MockPyth.mockOracleData(pid, 1337);
//2. CHAINLINK ORACLE
MockChainLink.mockOracleData(EthereumTokens.LINK, Fiat.USD, 1337); // LINK/USD

_executeAttack();
}

function _executeAttack() internal {
// PYTH
//1. PYTH ORACLE
PythUpgradable pyth = PythUpgradable(0x4305FB66699C3B2702D4d05CF36551390A4c69C6);
PythUpgradable.Price memory p = pyth.getPriceUnsafe(pid);
console.logInt(p.price);
_completeAttack();

// CHAINLINK

//2. CHAINLINK ORACLE
FeedRegistryInterface chainlinkRegistry = FeedRegistryInterface(0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf);
(, int256 answer,,,) = chainlinkRegistry.latestRoundData(EthereumTokens.LINK, Fiat.USD);
console.logInt(answer);
_completeAttack();
}

function _completeAttack() internal {}
Expand Down
57 changes: 29 additions & 28 deletions src/oracle/lib/MockChainLink.sol
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
pragma solidity ^0.8.0;

import "../../tokens/Tokens.sol";
import "forge-std/Vm.sol";

/**
* ChainlinkOracle is a library used to facilitate interactions with Chainlink Oracles.
* This includes functions to mock oracle data for testing and to retrieve context information
* specific to the blockchain environment the contract is operating in.
*/
library MockChainLink {
address constant HEVM_ADDRESS = address(bytes20(uint160(uint256(keccak256("hevm cheat code")))));
Vm constant vm = Vm(HEVM_ADDRESS);

struct Context {
EACAggregatorProxy aggregator;
FeedRegistryInterface registry;
}

/**
Expand All @@ -19,14 +24,26 @@ library MockChainLink {
* @param baseToken The token to get the price of.
* @param price The price of the base token in terms of the quote token.
*/
function mockOracleData(IERC20 quoteToken, IERC20 baseToken, uint256 price) internal {
function mockOracleData(IERC20 baseToken, address quoteToken, uint256 price) internal {
Context memory context = context();

// It's likely we can generalize this function to take a token pair to mock the returned price of, but we should provide a generic
// function which can be used to mock any oracle data, not just price data. This way the Oracle specific library can have their own
// wrapper function which serializes/deserializes the generic mock oracle data into the appropriate parameters.

// Code to mock the oracle call...
EACAggregatorProxy feed = context.registry.getFeed(baseToken, quoteToken);

(uint80 roundId,, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound) =
context.registry.latestRoundData(baseToken, quoteToken);

vm.mockCall(
address(context.registry),
abi.encodeCall(FeedRegistryInterface.latestRoundData, (baseToken, quoteToken)),
abi.encode(roundId, price, startedAt, updatedAt, answeredInRound)
);

//TODO: Mock the feed contract of the pair (latestRoundData)
}

/**
Expand All @@ -37,43 +54,27 @@ library MockChainLink {
*/
function context() internal view returns (Context memory) {
EACAggregatorProxy aggregator;
FeedRegistryInterface registry;

if (block.chainid == 1) {
// Ethereum mainnet
aggregator = EACAggregatorProxy(0x72AFAECF99C9d9C8215fF44C77B94B99C28741e8);
registry = FeedRegistryInterface(0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf);
} else {
revert("ChainlinkOracle: Chain not supported");
}

return Context(aggregator);
return Context(aggregator, registry);
}
}

interface FeedRegistryInterface {
function latestRoundData(IERC20 base, address quote)
external
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);

// /**
// * @dev Helper function which encode the mock oracle data
// * @param param1
// * @param param2
// * @param param3
// */
// function unpackData(type param1, type param2, type param3)
// internal
// pure
// returns (bytes memory data)
// {
// return abi.encode(param1, param2, param3);
// }

// /**
// * @dev Helper function which decodes the mock oracle data
// * @param data The data of the mock oracle call
// */
// function unpackData(bytes calldata data)
// internal
// pure
// returns (address token0, address token1, uint256 price)
// {
// (token0, token1, price) = abi.decode(data, (address, address, uint256));
// return (asset, amount, fee, params);
// }
function getFeed(IERC20 base, address quote) external view returns (EACAggregatorProxy aggregator);
}

interface EACAggregatorProxy {
Expand Down
2 changes: 1 addition & 1 deletion src/oracle/lib/MockPyth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -230,4 +230,4 @@ interface PythUpgradable {
function validTimePeriodSeconds() external view returns (uint256);
function version() external pure returns (string memory);
function wormhole() external view returns (address);
}
}
1 change: 0 additions & 1 deletion test/mocks/oracles/oracle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ contract MockOracleExampleTest is Test {
function setUp() public {
vm.createSelectFork("https://rpc.ankr.com/eth");


// vm.mockCall(0x4305FB66699C3B2702D4d05CF36551390A4c69C6, hex"96834ad3", abi.encode(1));

mockOracleExample = new MockOracleExample();
Expand Down

0 comments on commit 873624e

Please sign in to comment.