Algo Ssstablecoinsss

AI First Flight #2
Beginner FriendlyDeFi
EXP
View results
Submission Details
Impact: high
Likelihood: low
Invalid

No price > 0 check in oracle

Root + Impact

The root cause is in src/oracle_lib.vy:44-48. The function _stale_check_latest_round_data only validates the timestamp and round data returned by Chainlink. It never validates the actual price value itself. The price variable is of type int256 which can hold zero and negative values, but no assertion exists to reject these invalid values before returning them to the caller.

Impact:

  • Severity: High

  • Likelihood: Low — Chainlink is generally reliable but oracle failures and circuit breaker events have happened historically

  • If price = 0 is returned — every user's collateral is valued at $0, all health factors collapse, the entire protocol freezes

  • If price < 0 is returned — convert(price, uint256) reverts in Vyper, again freezing the protocol

  • All user funds become temporarily inaccessible until the oracle recovers

  • No mechanism exists in the protocol to recover from this state manually

  • Real world precedent: Venus Protocol 2023 suffered significant losses due to similar lack of oracle price validation

Description

  • Describe the normal behavior in one or more sentences

  • Explain the specific issue or problem in one or more sentences

assert updated_at != 0, "DSCEngine_StalePrice"
assert answered_in_round >= round_id, "DSCEngine_StalePrice"
seconds_since: uint256 = block.timestamp - updated_at
assert seconds_since <= TIMEOUT, "DSCEngine_StalePrice"
# ← missing: assert price > 0
*/Chainlink oracle malfunctions and returns price = 0
_stale_check_latest_round_data passes all checks and returns price = 0
_get_usd_value calculates 0 * ADDITIONAL_FEED_PRECISION * amount = 0
All collateral is now worth $0
Every user's health factor collapses
Protocol freezes — nobody can mint, redeem or liquidate
Real world precedent: Venus Protocol 2023*/

Risk

Likelihood:

  • Reason 1 // Describe WHEN this will occur (avoid using "if" statements)

  • Reason 2

Impact:

  • Impact 1

  • Impact 2

Proof of Concept

  1. Chainlink oracle experiences a failure or circuit breaker event and returns price = 0 from latestRoundData()

  2. _stale_check_latest_round_data in oracle_lib.vy passes all three existing checks — updated_at != 0, answered_in_round >= round_id, and seconds_since <= TIMEOUT — because none of them check the price value itself

  3. The zero price is returned to _get_usd_value in dsc_engine.vy

  4. The calculation becomes (0 * 1e10) * amount / 1e18 = 0 — every token is worth $0

  5. _get_account_collateral_value returns 0 for every user

  6. _calculate_health_factor returns 0 for every user with debt

  7. _revert_if_health_factor_is_broken triggers on every action — mint, redeem, burn all revert

  8. The protocol is completely frozen with no way to recover until the oracle price returns to normal

  9. This exact scenario has real world precedent — Venus Protocol on BNB Chain suffered losses due to similar oracle price validation failures where the protocol trusted an incorrect price returned by Chainlink without proper sanity checks

(
round_id, price, started_at, updated_at, answered_in_round
) = staticcall price_price.latestRoundData()
assert updated_at != 0, "DSCEngine_StalePrice"
assert answered_in_round >= round_id, "DSCEngine_StalePrice"
seconds_since: uint256 = block.timestamp - updated_at
assert seconds_since <= TIMEOUT, "DSCEngine_StalePrice"
# price is returned here with NO check that price > 0
return (round_id, price, started_at, updated_at, answered_in_round)

Recommended Mitigation

Add an explicit check that the price returned by Chainlink is greater than zero immediately after calling latestRoundData(). This single line addition would prevent a zero or negative price from ever reaching the protocol's calculations:

- remove this code
+ add this code
Add this check in src/oracle_lib.vy after getting round data:
+ assert price > 0, "DSCEngine__InvalidPrice
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 8 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!