Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: medium
Valid

ChainlinkARBOracle.sol contract allows the owner to set Chainlink price feeds for specific tokens using the addTokenPriceFeed function

Summary

The ChainlinkARBOracle.sol contract allows the owner to set Chainlink price feeds for specific tokens using the addTokenPriceFeed function. However, this can be exploited by malicious users who could replace the legitimate price feeds with their own, potentially reporting incorrect token prices.

Vulnerability Details

The vulnerability lies in the addTokenPriceFeed function, which allows the owner to set Chainlink price feeds for specific tokens without appropriate access controls. This function should be updated to include access controls to prevent unauthorized calls.

Vulnerable Code (ChainlinkARBOracle.sol):

function addTokenPriceFeed(address token, address feed) external onlyOwner {
if (token == address(0)) revert Errors.ZeroAddressNotAllowed();
if (feed == address(0)) revert Errors.ZeroAddressNotAllowed();
if (feeds[token] != address(0)) revert Errors.TokenPriceFeedAlreadySet();
feeds[token] = feed;
}

Impact

The impact of this vulnerability is significant, as it can lead to erroneous token pricing. Malicious users can replace legitimate Chainlink price feeds with their own, potentially causing financial losses and disrupting the proper functioning of the oracle.

Tools Used

Manual

Recommendations

Access Control:
Adding proper access controls to the addTokenPriceFeed function to restrict its usage to authorized addresses. In this example, we'll use a modified version of the Ownable contract from OpenZeppelin.

// Import Ownable.sol from OpenZeppelin
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
contract ChainlinkARBOracle is Ownable, Pausable {
// ...
// Modifier to restrict function to only the owner
modifier onlyOwnerOrAuthorized() {
require(msg.sender == owner() || msg.sender == authorizedAddress, "Not the owner or an authorized address");
_;
}
// Set an authorized address
address public authorizedAddress;
// Function to set the authorized address
function setAuthorizedAddress(address _authorizedAddress) external onlyOwner {
authorizedAddress = _authorizedAddress;
}
// Function to add Chainlink price feed
function addTokenPriceFeed(address token, address feed) external onlyOwnerOrAuthorized {
require(token != address(0), "Token address cannot be zero");
require(feed != address(0), "Feed address cannot be zero");
require(feeds[token] == address(0), "Token price feed already set");
feeds[token] = feed;
}
}

Introduced an authorizedAddress and a setAuthorizedAddress function, allowing the owner to designate additional addresses that can call restricted functions. Consider implementing multi-signature requirements for critical functions like setting price feeds. This adds an extra layer of security by requiring multiple parties to approve changes. You can also add time lock mechanisms that impose a delay between initiating a price feed change and its execution. This provides an opportunity for users to identify and prevent unauthorized changes.

Updates

Lead Judging Commences

hans Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

Chainlink price feed can not be updated

Impact: High Likelihood: Low

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.