oracle_lib.vy Triggers Division by Zero and Protocol Denial of ServiceThe _stale_check_latest_round_data function in oracle_lib.vy validates that updated_at != 0 and checks staleness against a timeout, but omits validating whether price > 0. If a Chainlink aggregator returns zero or negative price, callers converting the price to uint256 trigger division by zero in _get_token_amount_from_usd, resulting in an unhandled denial of service for liquidations.
In src/oracle_lib.vy:
Notice that price is returned as int256 without verifying price > 0.
In src/dsc_engine.vy, _get_token_amount_from_usd uses the price as a divisor:
If Chainlink returns 0 (such as during a market flash crash, sequencer halt, or aggregator misconfiguration), convert(0, uint256) * ADDITIONAL_FEED_PRECISION evaluates to 0. The integer division // 0 causes an immediate transaction revert.
If Chainlink returns a negative value, converting int256 to uint256 produces a two's-complement astronomical value, completely corrupting calculations.
Denial of Service: When the oracle returns zero, liquidators cannot liquidate any positions collateralized by the affected asset.
Corrupted Accounting: Negative prices cast to uint256 cause massive collateral undervaluation or unexpected reverts.
Verified in tests/unit/test_poc_audit.py::test_poc_oracle_zero_price_causes_failure:
Moccasin v0.4.4
Titanoboa v0.2.8
Pytest
Add explicit validation for price > 0 within _stale_check_latest_round_data:
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.