src/oracle_lib.vy
src/dsc_engine.vy
The _stale_check_latest_round_data() function in oracle_lib.vy validates price staleness but does not validate that the returned price value from latestRoundData() is greater than zero. The price field is typed as int256, and Chainlink can return 0 or negative values during circuit breaker events or oracle failures.
The unchecked price value is returned to dsc_engine.vy and passed directly to convert(price, uint256). In Vyper 0.4.0, this conversion reinterprets the two's-complement bit pattern: a value of -1 (int256) becomes 2^256 - 1 (uint256) ≈ 1.16×10^77. This causes the collateral USD value calculation to return an astronomically large number, bypassing the health factor check and allowing any user to mint unlimited amounts of DSC against any collateral.
Likelihood: Low
Chainlink returning zero or negative prices requires an oracle circuit breaker event or critical infrastructure failure — unlikely under normal conditions.
On ZKsync Era, oracle infrastructure is newer and less battle-tested than on Ethereum mainnet.
Impact: High
A price of -1 (int256) converts to ~1.16×10^77 USD value per token.
The health factor becomes effectively infinite — the attacker mints the protocol's entire DSC supply with 1 wei of collateral.
Protocol becomes instantly insolvent.
Severity: Medium
When the Chainlink ETH/USD oracle enters a circuit breaker state and returns a price of 0 or negative, the unsafe conversion allows an attacker to mint unlimited DSC. The attack requires only 1 wei of WETH as collateral.
Add an explicit positive price check in oracle_lib.vy before returning the price. This is the standard defensive pattern recommended by Chainlink documentation.
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.