Skip to content

Commit

Permalink
Add set/add feed functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
vreff committed Aug 28, 2023
1 parent 71e87f8 commit c8a56ca
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 18 deletions.
51 changes: 40 additions & 11 deletions contracts/src/v0.8/dev/automation/upkeeps/MercuryRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ import "../../../ChainSpecificUtil.sol";
| - Optimize gas consumption. |
-+---------------------------------------------------------------------------------------------------------------------*/
contract MercuryRegistry is AutomationCompatibleInterface, FeedLookupCompatibleInterface {
error DuplicateFeed(string feedId);
error FeedNotActive(string feedId);

// Feed object used for storing feed data.
// not included but contained in reports:
// - blocknumberUpperBound
Expand All @@ -41,6 +44,7 @@ contract MercuryRegistry is AutomationCompatibleInterface, FeedLookupCompatibleI
int192 ask; // the current ask price of the feed
string feedName; // the name of the feed
string feedId; // the id of the feed (hex encoded)
bool active; // true if the feed is being actively updated, otherwise false
}

// Report object obtained from off-chain Mercury server.
Expand Down Expand Up @@ -78,24 +82,49 @@ contract MercuryRegistry is AutomationCompatibleInterface, FeedLookupCompatibleI
) {
i_verifier = IVerifierProxy(verifier);

// Ensure correctly formatted constructor arguments.
require(feedIds.length == feedNames.length, "incorrect constructor args");

// Store desired deviation threshold and staleness seconds.
s_deviationPercentagePPM = deviationPercentagePPM;
s_stalenessSeconds = stalenessSeconds;

// Store desired feeds.
setFeeds(feedIds, feedNames);
}

function setFeeds(string[] memory feedIds, string[] memory feedNames) public {
// Ensure correctly formatted constructor arguments.
require(feedIds.length == feedNames.length, "incorrectly formatted feeds");

// Clear prior feeds.
for (uint256 i = 0; i < s_feeds.length; i++) {
s_feedMapping[s_feeds[i]].active = false;
}

// Assign new feeds.
for (uint256 i = 0; i < feedIds.length; i++) {
string memory feedId = feedIds[i];
if (s_feedMapping[feedId].active) {
revert DuplicateFeed(feedId);
}

s_feedMapping[feedId].feedName = feedNames[i];
s_feedMapping[feedId].feedId = feedId;
s_feedMapping[feedId].active = true;
}
s_feeds = feedIds;
}

function addFeeds(string[] memory feedIds, string[] memory feedNames) external {
for (uint256 i = 0; i < feedIds.length; i++) {
s_feedMapping[s_feeds[i]] = Feed({
feedName: feedNames[i],
feedId: feedIds[i],
price: 0,
bid: 0,
ask: 0,
observationsTimestamp: 0
});
string memory feedId = feedIds[i];
if (s_feedMapping[feedId].active) {
revert DuplicateFeed(feedId);
}

s_feedMapping[feedId].feedName = feedNames[i];
s_feedMapping[feedId].feedId = feedId;
s_feedMapping[feedId].active = true;

s_feeds.push(feedId);
}
}

Expand Down
34 changes: 27 additions & 7 deletions contracts/test/v0.8/foundry/automation/MercuryRegistry.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,30 @@ contract MercuryRegistryTest is Test {
vm.selectFork(vm.createFork("https://arbitrum-goerli.publicnode.com"));
vm.rollFork(BLOCK_NUMBER);

// Create Mercury Registry.
// Use a BTC feed and ETH feed.
feedIds = new string[](2);
feedIds[0] = s_BTCUSDFeedId;
feedIds[1] = s_ETHUSDFeedId;
string[] memory feedNames = new string[](2);
feedNames[0] = "BTC/USD";
feedNames[1] = "ETH/USD";
s_testRegistry = new MercuryRegistry(feedIds, feedNames, VERIFIER, DEVIATION_THRESHOLD, STALENESS_SECONDS);

// Initialize with BTC feed.
string[] memory initialFeedIds = new string[](1);
initialFeedIds[0] = feedIds[0];
string[] memory initialFeedNames = new string[](1);
initialFeedNames[0] = "BTC/USD";
s_testRegistry = new MercuryRegistry(
initialFeedIds,
initialFeedNames,
VERIFIER,
DEVIATION_THRESHOLD,
STALENESS_SECONDS
);

// Add ETH feed.
string[] memory addedFeedIds = new string[](1);
addedFeedIds[0] = feedIds[1];
string[] memory addedFeedNames = new string[](1);
addedFeedNames[0] = "ETH/USD";
s_testRegistry.addFeeds(addedFeedIds, addedFeedNames);
}

function testMercuryRegistry() public {
Expand Down Expand Up @@ -92,14 +108,16 @@ contract MercuryRegistryTest is Test {
int192 bid,
int192 ask,
string memory feedName,
string memory localFeedId
string memory localFeedId,
bool active
) = s_testRegistry.s_feedMapping(s_BTCUSDFeedId);
assertEq(observationsTimestamp, 1692732568); // Tuesday, August 22, 2023 7:29:28 PM
assertEq(bid, 2585674416498); // $25,856.74416498
assertEq(price, 2585711126720); // $25,857.11126720
assertEq(ask, 2585747836943); // $25,857.47836943
assertEq(feedName, "BTC/USD");
assertEq(localFeedId, s_BTCUSDFeedId);
assertEq(active, true);

// Obtain mercury report off-chain (for August 23 BTC/USD price & ETH/USD price)
values = new bytes[](2);
Expand Down Expand Up @@ -185,14 +203,16 @@ contract MercuryRegistryTest is Test {
int192 bid,
int192 ask,
string memory feedName,
string memory localFeedId
string memory localFeedId,
bool active
) = s_testRegistry.s_feedMapping(s_BTCUSDFeedId);
assertEq(observationsTimestamp, 1692732568); // Tuesday, August 22, 2023 7:29:28 PM
assertEq(bid, 2585674416498); // $25,856.74416498
assertEq(price, 2585711126720); // $25,857.11126720
assertEq(ask, 2585747836943); // $25,857.47836943
assertEq(feedName, "BTC/USD");
assertEq(localFeedId, s_BTCUSDFeedId);
assertEq(active, true);

// Obtain mercury report off-chain (for August 23 BTC/USD price & ETH/USD price)
values = new bytes[](2);
Expand Down

0 comments on commit c8a56ca

Please sign in to comment.