- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control. - Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities. - Created .gitmodules to include OpenZeppelin contracts as a submodule. - Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment. - Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks. - Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring. - Created scripts for resource import and usage validation across non-US regions. - Added tests for CCIP error handling and integration to ensure robust functionality. - Included various new files and directories for the orchestration portal and deployment scripts.
84 lines
2.3 KiB
Solidity
84 lines
2.3 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.19;
|
|
|
|
import {Test, console} from "forge-std/Test.sol";
|
|
import {Aggregator} from "../contracts/oracle/Aggregator.sol";
|
|
|
|
contract AggregatorTest is Test {
|
|
Aggregator public aggregator;
|
|
address public admin = address(1);
|
|
address public transmitter = address(2);
|
|
|
|
function setUp() public {
|
|
vm.prank(admin);
|
|
aggregator = new Aggregator(
|
|
"ETH/USD Price Feed",
|
|
admin,
|
|
60, // heartbeat: 60 seconds
|
|
50 // deviationThreshold: 0.5% (50 basis points)
|
|
);
|
|
|
|
vm.prank(admin);
|
|
aggregator.addTransmitter(transmitter);
|
|
}
|
|
|
|
function testUpdateAnswer() public {
|
|
vm.prank(transmitter);
|
|
aggregator.updateAnswer(2000e8);
|
|
|
|
(uint80 roundId, int256 answer, , , ) = aggregator.latestRoundData();
|
|
assertEq(roundId, 1);
|
|
assertEq(answer, 2000e8);
|
|
}
|
|
|
|
function testHeartbeat() public {
|
|
vm.prank(transmitter);
|
|
aggregator.updateAnswer(2000e8);
|
|
|
|
// Fast forward time
|
|
vm.warp(block.timestamp + 61);
|
|
|
|
vm.prank(transmitter);
|
|
aggregator.updateAnswer(2001e8);
|
|
|
|
(uint80 roundId, , , , ) = aggregator.latestRoundData();
|
|
assertEq(roundId, 2);
|
|
}
|
|
|
|
function testDeviationThreshold() public {
|
|
vm.prank(transmitter);
|
|
aggregator.updateAnswer(2000e8);
|
|
|
|
// 1% deviation should trigger new round
|
|
vm.prank(transmitter);
|
|
aggregator.updateAnswer(2020e8);
|
|
|
|
(uint80 roundId, , , , ) = aggregator.latestRoundData();
|
|
assertEq(roundId, 2);
|
|
}
|
|
|
|
function testOnlyTransmitter() public {
|
|
vm.expectRevert("Aggregator: only transmitter");
|
|
aggregator.updateAnswer(2000e8);
|
|
}
|
|
|
|
function testAddTransmitter() public {
|
|
address newTransmitter = address(3);
|
|
|
|
vm.prank(admin);
|
|
aggregator.addTransmitter(newTransmitter);
|
|
|
|
assertTrue(aggregator.isTransmitter(newTransmitter));
|
|
}
|
|
|
|
function testPause() public {
|
|
vm.prank(admin);
|
|
aggregator.pause();
|
|
|
|
vm.prank(transmitter);
|
|
vm.expectRevert("Aggregator: paused");
|
|
aggregator.updateAnswer(2000e8);
|
|
}
|
|
}
|
|
|