The smart contract DSCEngine.sol
contains two functions, getTokenAmountFromUsd
and getUsdValue
, that fetch token prices from an external Oracle. The vulnerability lies in the incorrect calculation when converting a negative int256
value to uint256
, which can lead to large positive numbers instead of the expected negative value.
The functions getTokenAmountFromUsd
and getUsdValue
are designed to retrieve the price of a token in USD from an external Oracle, which returns the price as an int256
value. The vulnerability arises when these functions directly use uint256(price)
in calculations without verifying whether the price is non-negative.
The issue occurs when the int256
price is negative. Converting a negative int256
to uint256
follows two's complement representation, resulting in a large positive value instead of the original negative value. As a consequence, the calculations produce unexpected and inaccurate results.
It's worth noting that the Chainlink Data Feeds use int
instead of uint
because some prices can be negative, for instance, when oil futures dropped below 0. However, in the provided code, the price obtained from the Chainlink Data Feed is converted from int256
to uint256
without checking if it's negative which can lead to incorrect calculations.
Reference: Stack Overflow link
The vulnerability can result in incorrect token amount and USD value calculations, leading to disruptions in the token's economic balance and potential financial losses for users. If the price is negative and mistakenly converted to a large positive value, users may receive excessive or insufficient token amounts, causing imbalances in the token's supply. Additionally, inaccurate USD value calculations can misrepresent token asset values, leading to incorrect financial decisions based on undervalued or overvalued assets. This can undermine user confidence in the contract's reliability and functionality.
VS Code
To address the issue make sure that the price
variable is a non-negative value before converting it from a int256
into a uint256
value.
Here is an updated version for both of the functions:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.