The description for this contest is as follows:
This project is meant to be a stablecoin where users can deposit WETH and WBTC in exchange for a token that will be pegged to the USD. The system is meant to be such that someone could fork this codebase, swap out WETH & WBTC for any basket of assets they like, and the code would work the same.
This makes it clear that WBTC is one of the tokens that MUST be supported.
In other words WBTC is one of the tokens (in addition to WETH) that is supported by default and any issues that arise due to using it cannot be attributed to an error on the deployer's end.
The root cause is that the WBTC <-> USD conversion is faulty.
WBTC has 6 decimals (https://etherscan.io/token/0x2260fac5e5542a773aa44fbcfedf7c193bc2c599#readContract) whereas the DSCEngine
contract assumes that it has 18 decimals.
A user sending WBTC to the contract actually sends a whole WBTC token.
According to the contract logic this amount would be treated as a tiny fraction of a whole WBTC token (). (Link)
The same issue exists in the reverse calculation in the getTokenAmountFromUsd
function (Link) which outputs the token amount with 18 decimals as opposed to adjusting for a specific token's decimals.
The behavior described so far can result in a direct loss of funds for the user.
In the test suite that is part of the repository, the WBTC/USD price is set to $1000.
And so if we provide as the amount of WBTC, the resulting amount of USD should be 1000e18$).
However the value that is logged by the following test is (only a tiny fraction of 1 USD).
What follows from this incorrect calculation is that any WBTC collateral is essentially worthless.
Here's a scenario how a loss of funds can occur:
The user has WETH and WBTC collateral. He's got so much WETH collateral that he doesn't notice that his WBTC is essentially treated as worthless. I.e. even though his WBTC is treated as worthless he has enough collateral to mint DSC
Price of WETH drops and the user can be liquidated
A liquiditar liquidates the user by providing a tiny amount of DSC and receiving WBTC
Obviously the WBTC is worth much more by a factor of
In summary what happened is that the user got liquidated earlier than necessary because of the miscalculated WBTC value and the liquidator received WBTC by paying off a negligible amount of debt since the protocol treats the WBTC as essentially wothless.
As described above this can lead to a direct loss of funds.
Manual Review, Foundry
In the DSCEngine.getUsdValue
as well as the DSCEngine.getTokenAmountFromUsd
functions there needs to be conversion such that the results are accurately calculated for tokens that do not have 18 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.