Algo Ssstablecoinsss

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

[H-03] Missing Validation for Non-Positive Oracle Price Causes Protocol DoS

Root + Impact

Description

  • The oracle_lib::_stale_check_latest_round_data() function validates stale data conditions but does not verify that the returned oracle price is strictly greater than zero.

  • As a result, downstream functions in DSCEngine that convert the returned int256 price to uint256 using convert(price, uint256) may revert if the price is negative, or cause division-by-zero errors if the price equals zero.

  • This can render core protocol functions unusable.

(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"

There is no validation that price > 0.

However, in dsc_engine.vy, price is used in arithmetic operations:

convert(price, uint256)
(usd_amount_in_wei * PRECISION) // (convert(price, uint256) * ADDITIONAL_FEED_PRECISION)

If:

  • price == 0 → division by zero

  • price < 0 → conversion to uint256 reverts

This affects:

  • get_usd_value()

  • get_token_amount_from_usd()

  • liquidate()

  • _health_factor()

  • redeem_collateral()

Risk

Likelihood

  • Low under normal Chainlink assumptions.

  • Medium if oracle misconfiguration, feed migration, heartbeat disruption, or integration errors occur.

  • Negative values are possible since Chainlink returns int256.

Impact

If the oracle returns a non-positive value:

  • Division by zero

  • Unexpected reverts

  • Liquidations become impossible

  • Minting/redemption fail

  • Full protocol freeze

Core functionality becomes unusable until oracle values normalize.

This effectively creates a protocol-wide DoS condition

Proof of Concept

def test_negative_price_breaks_protocol(dsce, weth, eth_usd):
eth_usd.updateAnswer(-1)
with boa.reverts():
dsce.get_usd_value(weth, 1)
def test_zero_price_feed_breaks_token_amount_from_usd(dsce, weth, eth_usd):
eth_usd.updateAnswer(0)
with boa.reverts():
dsce.get_token_amount_from_usd(weth, to_wei(100, "ether"))

Both tests confirm protocol reverts when price is non-positive.

Recommended Mitigation

Add explicit validation in oracle_lib:

assert price > 0, "DSCEngine_InvalidPrice

Updated Secure Implementation:

(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"
assert price > 0, "DSCEngine_InvalidPrice"
assert block.timestamp - updated_at <= TIMEOUT, "DSCEngine_StalePrice"
return (round_id, price, started_at, updated_at, answered_in_round)

Why This Fix Works

  • Prevents negative values from reaching convert(price, uint256

  • Prevents division-by-zero in _get_token_amount_from_usd

  • Ensures invariant: “oracle price must represent valid asset value”

  • Centralizes validation at oracle boundary (cleaner architecture)

  • Guarantees downstream math safety

Edge Case Considerations:

  • If Chainlink feed legitimately reports 0 (extreme asset collapse), protocol freezing is correct behavior.

  • Explicit check improves clarity over implicit arithmetic revert.

  • Ensures predictable failure mode with explicit revert reason.

Defense-in-Depth Improvements:

  • Add upper bound sanity check (e.g., reject absurd price spikes)

  • Emit event when invalid price detected

  • Implement emergency pause mechanism when oracle invalid

  • Add monitoring alert for price ≤ 0

Security Design Principle:

This issue violates:

“Validate external data at system boundary before arithmetic use.”

Oracle data is untrusted input and must be sanitized before internal state math.

Conclusion:

The protocol relies on oracle price integrity but does not defensively validate non-positive values.

This creates a system-wide denial of service condition when price ≤ 0, affecting all core functions.

Adding explicit price validation eliminates this attack surface and improves protocol robustness.

This ensures non-positive oracle values cannot propagate into protocol math.

Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 3 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!