diff --git a/.gitmodules b/.gitmodules index 4075a17..49c7d0f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "contracts/lib/solidity-merkle-trees"] path = contracts/lib/solidity-merkle-trees url = git@github.com:michaelkaplan13/solidity-merkle-trees.git +[submodule "contracts/lib/chainlink"] + path = contracts/lib/chainlink + url = https://github.com/smartcontractkit/chainlink diff --git a/contracts/lib/chainlink b/contracts/lib/chainlink new file mode 160000 index 0000000..883c9f9 --- /dev/null +++ b/contracts/lib/chainlink @@ -0,0 +1 @@ +Subproject commit 883c9f9059c259ca17454703b57521ea9ac166cb diff --git a/contracts/remappings.txt b/contracts/remappings.txt index 0f5b009..a1aebd0 100644 --- a/contracts/remappings.txt +++ b/contracts/remappings.txt @@ -1,2 +1,3 @@ @solidity-merkle-trees=lib/solidity-merkle-trees/src/ @subnet-evm=lib/teleporter/contracts/lib/subnet-evm/contracts/ +@chainlink=lib/chainlink/contracts/src/v0.8/shared/ diff --git a/contracts/src/PriceFeedImporter.sol b/contracts/src/PriceFeedImporter.sol index d8d6f90..a50851a 100644 --- a/contracts/src/PriceFeedImporter.sol +++ b/contracts/src/PriceFeedImporter.sol @@ -6,6 +6,7 @@ pragma solidity 0.8.18; import {EVMEventInfo, EventImporter} from "./EventImporter.sol"; +import {AggregatorV3Interface} from "@chainlink/interfaces/AggregatorV3Interface.sol"; /** * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE. @@ -72,7 +73,13 @@ contract PriceFeedImporter is EventImporter, AggregatorV3Interface { _; } - constructor(bytes32 sourceBlockchainID_, address sourceOracleAggregator_, uint8 decimals_, string memory description_, uint256 version_) { + constructor( + bytes32 sourceBlockchainID_, + address sourceOracleAggregator_, + uint8 decimals_, + string memory description_, + uint256 version_ + ) { sourceBlockchainID = sourceBlockchainID_; sourceOracleAggregator = sourceOracleAggregator_; decimals = decimals_; @@ -80,23 +87,6 @@ contract PriceFeedImporter is EventImporter, AggregatorV3Interface { version = version_; } - function latestAnswer() external view returns (int256) { - (, int256 answer,,,) = latestRoundData(); - return answer; - } - - function latestRound() external view returns (uint256) { - (uint80 roundID,,,,) = latestRoundData(); - return roundID; - } - - // solhint-disable-next-line private-vars-leading-underscore - function getAnswer(uint256 _roundID) external view returns (int256) { - if (_roundID > 0xFFFFFFFF) return 0; - (, int256 answer,,,) = getRoundData(uint80(_roundID)); - return answer; - } - // solhint-disable-next-line private-vars-leading-underscore function getRoundData(uint80 _roundID) public view returns (uint80, int256, uint256, uint256, uint80) { Round memory round = rounds[_roundID]; diff --git a/contracts/test/PriceFeedImporterTests.sol b/contracts/test/PriceFeedImporterTests.sol index fc09566..892d74b 100644 --- a/contracts/test/PriceFeedImporterTests.sol +++ b/contracts/test/PriceFeedImporterTests.sol @@ -23,6 +23,7 @@ contract PriceFeedImporterTest is Test { address public constant SOURCE_ORACLE_AGGREGATOR = 0x154baB1FC1D87fF641EeD0E9Bc0f8a50D880D2B6; PriceFeedImporterMock public priceFeedImporter; + bytes32 public ANSWER_UPDATED_EVENT_SIGNATURE; event AnswerUpdated(int256 currentAnswer, uint80 roundID, uint256 updatedAt); event EventImported( @@ -35,6 +36,7 @@ contract PriceFeedImporterTest is Test { function setUp() public virtual { priceFeedImporter = new PriceFeedImporterMock(); + ANSWER_UPDATED_EVENT_SIGNATURE = priceFeedImporter.ANSWER_UPDATED_EVENT_SIGNATURE(); } function testSetPriceFeed() public { @@ -57,20 +59,27 @@ contract PriceFeedImporterTest is Test { function testIncreasingRoundID() public { priceFeedImporter.importEvent(buildEVMEvent(0, 0, 1)); priceFeedImporter.importEvent(buildEVMEvent(0, 1, 1)); - vm.revertWith("roundID should be monotonically increasing"); + vm.expectRevert("roundID should be monotonically increasing"); priceFeedImporter.importEvent(buildEVMEvent(0, 0, 1)); + vm.expectRevert("roundID should be monotonically increasing"); + priceFeedImporter.importEvent(buildEVMEvent(0, 1, 1)); } function testHistoricalRoundData() public { - priceFeedImporter.importEvent(buildEVMEvent(0, 0, 1)); - priceFeedImporter.importEvent(buildEVMEvent(0, 1, 1)); - vm.revertWith("roundID should be monotonically increasing"); - priceFeedImporter.importEvent(buildEVMEvent(0, 0, 1)); + priceFeedImporter.importEvent(buildEVMEvent(10, 0, 1)); + priceFeedImporter.importEvent(buildEVMEvent(11, 1, 1)); + (, int256 answer,,,) = priceFeedImporter.getRoundData(0); + assertEq(answer, 10); + (, answer,,,) = priceFeedImporter.getRoundData(1); + assertEq(answer, 11); + vm.expectRevert("No data"); + (, answer,,,) = priceFeedImporter.getRoundData(2); } - function buildEVMEvent(int256 answer, uint80 roundID, uint256 updatedAt) private view returns (EVMEventInfo memory) { + uint256 blockNumber = 0; + function buildEVMEvent(int256 answer, uint80 roundID, uint256 updatedAt) private returns (EVMEventInfo memory) { bytes32[] memory topics = new bytes32[](3); - topics[0] = priceFeedImporter.ANSWER_UPDATED_EVENT_SIGNATURE(); + topics[0] = ANSWER_UPDATED_EVENT_SIGNATURE; topics[1] = bytes32(uint256(answer)); topics[2] = bytes32(uint256(uint80(roundID))); @@ -80,9 +89,11 @@ contract PriceFeedImporterTest is Test { data: abi.encode(bytes32(updatedAt)) }); + blockNumber += 1; + return EVMEventInfo({ blockchainID: bytes32(0), - blockNumber: 1, + blockNumber: blockNumber, txIndex: 0, logIndex: 0, log: log