Algo Ssstablecoinsss

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

[M-04] — Missing stale price check

Root + Impact

Description

  • The protocol uses Chainlink price feeds via oracle_lib._stale_check_latest_round_data(...) when converting collateral to USD value (_get_usd_value) and when deriving token amounts from USD (_get_token_amount_from_usd).

  • However, stale price validation is only enforced inside the helper oracle_lib._stale_check_latest_round_data(...) and not at all call sites that use price data. Specifically:


  • _get_usd_value calls oracle_lib._stale_check_latest_round_data(...) and returns price-based USD value.


  • _get_token_amount_from_usd also calls oracle_lib._stale_check_latest_round_data(...).

  • Oracle library enforces freshness via updated_at != 0, answered_in_round ≥ round_id, and block.timestamp – updated_at ≤ TIMEOUT.

  • While the stale-check library exists, there is no protocol-level stale price threshold

validation or reversion handling outside these functions. For example:
No MAX_STALENESS constant is defined in the engine itself.
Health factor and collateral valuation logic assume price feeds always succeed and do not wrap price calls in protocols that enforce limits at all external entrypoints.

Risk

Likelihood:

  • Reason 1 Oracle staleness can occur due to feed downtime.

  • Reason 2 Not all price-dependent code paths enforce protocol-level stale checks.

Impact:

  • Impact 1 Incorrect collateral valuations.

  • Impact 2 Improper health factor computation.

  • Impact 3 Undercollateralized minting or incorrect liquidations.

Proof of Concept

  • If Chainlink feed stops updating but still returns a last round with recent enough value to satisfy the minimal library thresholds, the protocol will use older price data.

  • A price drop in the market won’t be reflected in protocol valuations until the feed updates, while the protocol continues to operate normally.

Expected behavior:
Protocol should enforce explicit age limits (e.g., MAX_STALENESS) at every price read and revert if price data is outdated.

Actual behavior:
Stale price detection only happens via the internal library checks; there is no protocol-wide consistency check or configurable staleness threshold applied at all external functions.

Recommended Mitigation

  • Define Protocol-Level Staleness Threshold
    Introduce MAX_STALENESS in the engine and enforce it consistently for all price reads before collateral or debt computations.

  • Wrap All Oracle Calls with Freshness Assertions
    Ensure top-level functions explicitly validate:

updated_at, answered_in_round = ...
assert updated_at != 0
assert answered_in_round >= round_id
assert block.timestamp - updated_at <= MAX_STALENESS
  • Increase Defense-in-Depth

Use a dedicated oracle wrapper that enforces price freshness and positive pricing before returning results to the engine.

Conclusion

While the protocol uses an oracle library that performs basic stale checks, it lacks consistent, external stale price enforcement across all price-dependent paths. This exposes the system to stale price risk, potentially enabling incorrect collateral valuation, health factor miscalculations, and incorrect minting or liquidation outcomes. Enforcing explicit stale price validation at each entrypoint strengthens protocol safety and price accuracy.

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!