Algo Ssstablecoinsss

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

Unsafe Oracle Price Casting Allows Infinite Minting and Protocol Insolvency

Root + Impact

Description

  • The protocol relies on external price feeds to determine the USD value of deposited collateral and to calculate liquidation amounts. Under normal operation, oracle prices are expected to always return valid positive values representing the asset price in USD.

  • However, the contract does not validate that the oracle price returned from the price feed is strictly greater than zero before casting it from int256 to uint256. If the oracle returns a zero or negative price, the conversion results in either a division-by-zero condition or an extremely large unsigned integer value, leading to incorrect collateral valuation and broken health factor calculations.

This allows users to mint an excessive amount of DSC or causes protocol-wide denial of service during liquidation and accounting operations.

# _get_usd_value
@internal
@view
def _get_usd_value(token: address, amount: uint256) -> uint256:
...
(
round_id, price, started_at, updated_at, answered_in_round
) = oracle_lib._stale_check_latest_round_data(price_feed.address)
# @> price is not validated before conversion
return (
(convert(price, uint256) * ADDITIONAL_FEED_PRECISION) * amount
) // PRECISION
# _get_token_amount_from_usd
@internal
@view
def _get_token_amount_from_usd(token: address, usd_amount_in_wei: uint256) -> uint256:
...
(
round_id, price, started_at, updated_at, answered_in_round
) = oracle_lib._stale_check_latest_round_data(price_feed.address)
# @> unsafe conversion used as denominator
return (
(usd_amount_in_wei * PRECISION) //
(convert(price, uint256) * ADDITIONAL_FEED_PRECISION)
)

Risk

Likelihood:

  • Chainlink price feeds may legitimately return zero or negative values during oracle failure, migration rounds, sequencer downtime, or invalid reporting rounds.

  • The system is deployed on zkSync Era, where sequencer interruptions and oracle edge cases are realistic operational scenarios.

Impact:

  • Negative prices converted to uint256 become extremely large values, artificially inflating collateral valuation and allowing excessive DSC minting.

  • A zero price causes division-by-zero during liquidation and valuation, resulting in protocol-wide denial of service and frozen liquidations.

Proof of Concept

The protocol assumes that oracle prices are always positive. However, Chainlink price feeds return signed integers (int256), and under abnormal oracle conditions a round may return a negative or zero price.

Because the returned value is directly cast to uint256 without validation, the system misinterprets invalid oracle data as a valid large positive price.

Scenario:
1. Oracle returns price = -1 due to faulty round.
2. convert(price, uint256) produces a very large uint256 value.
3. _get_usd_value() calculates an enormous collateral USD value.
4. health_factor becomes extremely high.
5. Attacker deposits minimal collateral.
6. Attacker mints disproportionate amounts of DSC without liquidation risk.
Result:
Protocol becomes insolvent due to unbacked DSC supply.

Recommended Mitigation

Validate oracle prices before performing any arithmetic or casting.

(
round_id, price, started_at, updated_at, answered_in_round
) = oracle_lib._stale_check_latest_round_data(price_feed.address);
+ assert price > 0, "InvalidOraclePrice";
return (
(convert(price, uint256) * ADDITIONAL_FEED_PRECISION) * amount
) // PRECISION;

Apply the same validation inside _get_token_amount_from_usd.

Updates

Lead Judging Commences

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