The high-risk vulnerability in this contract stems from the use of assert
statements to validate price data from Chainlink oracles. This creates a Denial of Service (DoS) scenario where the contract can be rendered completely unusable if the price data becomes stale or is delayed. The contract will revert every time stale price data is encountered, which can lock funds and prevent interactions with the protocol.
Location: The vulnerability occurs due to the assert statements in the _stale_check_latest_round_data
function.
Code:
Explanation:
On lines 44-48, the contract checks if the price data has been updated recently by verifying the updated_at
field and calculating the time since the last update. If any of these checks fail (for instance, if the updated_at
is 0
, if the feed is outdated, or if the price feed hasn’t been updated within the specified TIMEOUT
), the contract will revert with the error message "DSCEngine_StalePrice"
.
Risk:
If the price data is stale (or if there's an issue with the Chainlink oracle), the contract will stop functioning, resulting in a Denial of Service (DoS). This could occur if Chainlink experiences delays in updating prices, or if the data isn't available at all.
Denial of Service (DoS): If the oracle feed fails to update (e.g., due to network issues or price feed delays), the contract will continuously fail at the assertion checks, rendering the contract inoperable. This can lock funds and halt interactions with the protocol.
Protocol Inactivity: A stalled Chainlink feed could cause the entire protocol to freeze, preventing users from interacting with the smart contract until the price feed is restored, which might be highly disruptive.
Loss of Funds: If the protocol's functionality is halted for an extended period, funds locked in the contract could be inaccessible. This is particularly problematic for users who rely on timely price updates to execute trades or liquidations.
User Frustration: Frequent failure of price updates could lead to user dissatisfaction and reduce trust in the protocol, especially in the event of a market downturn or volatility.
Staticcall: This method is used to interact with Chainlink’s AggregatorV3Interface, but it doesn’t have a built-in fallback or error recovery mechanism.
Solidity assert
: This is used for the validation checks, and while it’s useful for ensuring certain conditions, its failure leads to reverts without providing detailed user-friendly error messages.
Use require
instead of assert
: Replace assert
statements with require
to allow more user-friendly error messages and ensure that users can get meaningful feedback when the contract fails. This will also reduce the risk of triggering unintended reverts.
Code:
Implement a Fallback or Alternative Feed: Consider implementing a secondary data feed or fallback mechanism for price data, so that if Chainlink fails, the contract can continue functioning by using an alternative oracle or price source. This reduces reliance on a single oracle and can prevent protocol downtime.
Monitor Oracle Health: Introduce additional checks or mechanisms to actively monitor Chainlink’s feed health and provide alerts if the data becomes stale. Implement a recovery process where the contract can be automatically fixed or reactivated when price data becomes available again.
Graceful Error Handling: Instead of completely halting the contract when data is stale, allow for a grace period or temporary fallback mode that would let users interact with the protocol under specific, safe conditions while the price feed issue is being resolved.
Link To File: https://github.com/Cyfrin/2024-12-algo-ssstablecoinsss/blob/main/src/oracle_lib.vy
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.