feat: finish up challenges
Some checks failed
Lint / ci (lts/*, ubuntu-latest) (push) Has been cancelled

This commit is contained in:
han
2026-01-26 18:22:19 +07:00
parent b330aba2b4
commit c18c66cca1
22 changed files with 8397 additions and 58 deletions

View File

@@ -60,7 +60,11 @@ contract WhitelistOracle {
* @dev Creates a new SimpleOracle instance and adds it to the oracles array.
* @param _owner The address that will own the newly created oracle and can update its price
*/
function addOracle(address _owner) public onlyOwner {}
function addOracle(address _owner) public onlyOwner {
SimpleOracle newOracle = new SimpleOracle(_owner);
oracles.push(newOracle);
emit OracleAdded(address(newOracle), _owner);
}
/**
* @notice Removes an oracle from the whitelist by its array index (only contract owner)
@@ -68,7 +72,18 @@ contract WhitelistOracle {
* Reverts with IndexOutOfBounds, if the provided index is >= oracles.length.
* @param index The index of the oracle to remove from the oracles array
*/
function removeOracle(uint256 index) public onlyOwner {}
function removeOracle(uint256 index) public onlyOwner {
uint256 oraclesSize = oracles.length;
if (index >= oraclesSize) revert IndexOutOfBounds();
address deletedOracle = address(oracles[index]);
if (index != oraclesSize - 1) {
oracles[index] = oracles[oraclesSize - 1];
}
oracles.pop();
emit OracleRemoved(deletedOracle);
}
/**
* @notice Returns the aggregated price from all active oracles using median calculation
@@ -76,7 +91,28 @@ contract WhitelistOracle {
* of remaining valid prices. Uses StatisticsUtils for sorting and median calculation.
* @return The median price from all active oracles
*/
function getPrice() public view returns (uint256) {}
function getPrice() public view returns (uint256) {
if (oracles.length == 0) revert NoOraclesAvailable();
uint256[] memory prices = new uint256[](oracles.length);
uint256 priceIndex = 0;
uint256 currentTime = block.timestamp;
for (uint256 i = 0; i < oracles.length; i++) {
(uint256 price, uint256 timestamp) = oracles[i].getPrice();
if (currentTime - timestamp < STALE_DATA_WINDOW) {
prices[priceIndex] = price;
priceIndex++;
}
}
uint256[] memory fixedPrices = new uint256[](priceIndex);
for (uint256 i = 0; i < priceIndex; i++) {
fixedPrices[i] = prices[i];
}
fixedPrices.sort();
return fixedPrices.getMedian();
}
/**
* @notice Returns the addresses of all oracles that have updated their price within the last STALE_DATA_WINDOW
@@ -85,5 +121,24 @@ contract WhitelistOracle {
* for gas optimization.
* @return An array of addresses representing the currently active oracle contracts
*/
function getActiveOracleNodes() public view returns (address[] memory) {}
function getActiveOracleNodes() public view returns (address[] memory) {
address[] memory activeOracles = new address[](oracles.length);
uint256 oracleIndex = 0;
uint256 currentTime = block.timestamp;
for (uint256 i = 0; i < oracles.length; i++) {
(, uint256 timestamp) = oracles[i].getPrice();
if (currentTime - timestamp < STALE_DATA_WINDOW) {
activeOracles[oracleIndex] = address(oracles[i]);
oracleIndex++;
}
}
address[] memory fixedActiveOracles = new address[](oracleIndex);
for (uint256 i = 0; i < oracleIndex; i++) {
fixedActiveOracles[i] = activeOracles[i];
}
return fixedActiveOracles;
}
}