Denial-of-Service Attack caused by external call
Denial-of-Service Attack caused by external call typically occurs in smart contracts deployed on blockchain networks like Ethereum. In such attacks, an adversary exploits vulnerabilities in a contract's design to initiate external calls to untrusted contracts or external addresses, which can lead to various forms of disruption or abuse.
Details
When the protocol wants to use Chainlink's Oracle data feed to get a collateral token’s price, the fixed price for the token should not be set. When the fixed price is not set for the token, calling the Oracle
contract's viewPrice()
function…
function viewPrice(address token, uint collateralFactorBps) external view returns (uint) {
if(fixedPrices[token] > 0) return fixedPrices[token];
if(feeds[token].feed != IChainlinkFeed(address(0))) {
// get price from feed
uint price = feeds[token].feed.latestAnswer();
require(price > 0, "Invalid feed price");
// normalize price
[...]
}
will execute
uint price = feeds[token].feed.latestAnswer();
It is possible that Chainlink’s “multisigs can immediately block access to price feeds at will”[1]. When this occurs, executing
feeds[token].feed.latestAnswer()
will revert.
Calling the viewPrice
function also reverts, which causes denial of service.
This means that every function dependent of viewPrice()
will potentially end up being reverted.
Recomendation
The Oracle
contract's viewPrice
functions can be updated to refactor
feeds[token].feed.latestAnswer()
into
try feeds[token].feed.latestAnswer() returns (int256 price) { ... }
catch Error(string memory) { ... }
The logic for getting the collateral token's price from the Chainlink oracle data feed should be placed in the try
block while some fallback logic when access to the Chainlink oracle data feed is denied should be placed in the catch
block.
Sources
- ↑ openzeppelin.com - Smart Contract Security Guidelines #3: The Dangers of Price Oracles [1]