When a user deposits wBTC into the system, their collateralValue in terms of USD is inaccurately calculated, resulting in a health factor below the threshold of 1e18, even if the price of BTC remains unchanged. This miscalculation exposes the user to the risk of immediate liquidation, potentially leading to the loss of their wBTC holdings.
wBTC is a token with 8 decimals, so when a user deposits wBTC into the system, the amount parameter will also have 8 decimals. For example, if a user deposits 1 BTC, they will send 1 * 1e8
as the amount parameter, and the s_collateralDeposited
state will be updated as follows:
s_collateralDeposited[user][wBTC] = 1 * 1e8;
As a result, the getAccountCollateralValue()
function will return a significantly lower amount of USD value (in 8 decimals instead of 18) that it should in case the user deposits wBTC to the system, and the healthFactor of the user will be with 8 decimals which will be significantly lower than the minimum health factor (18 decimals).
This means that right after depositing wBTC to the system, and without minting DSC tokens the user's wBTC is in a risk of liquidation since his startingUserHealthFactory
is lower than the MIN_HEALTH_FACTOR
.
Any other malicious user can mint DSC tokens using wETH collateral and steal the wBTC collateral deposited by the vulnerable user.
Users will loose the wBTC right after depositing it to the system.
VSCode
The problem relies of a wrong USD value calculation of wBTC collateral (in 8 decimals instead of 18).
In order to fix the issue, modify the getUsdValue(address token, uint256 amount)
function so it will take into consideration the token's decimals.
Change this:
uint256 usdValue = ((uint256(price) * ADDITIONAL_FEED_PRECISION) * amount) / PRECISION;
To that:
uint256 usdValue = ((uint256(price) * ADDITIONAL_FEED_PRECISION) * amount) / token.decimals();
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.