There is a double-spending vulnerability in the DSCEngine
contract, leading to a disruption of the DSC token.
While constructing the DSCEngine
contract, the whitelisted collateral tokens will be registered along with their corresponding price feed addresses. However, the registration process does not verify that a token cannot be registered twice.
For instance, assume that the ETH address is inputted in the array tokenAddresses
twice, the ETH address will also be pushed into the array s_collateralTokens
twice.
Subsequently, when the contract executes the getAccountCollateralValue()
to compute users' collateral value, the function will process on the ETH address twice. In other words, if a user/attacker deposits 10 ETH as collateral, the getAccountCollateralValue()
will return 20 ETH (in USD value), leading to a double-spending issue.
With this double-spending vulnerability, an attacker can deposit ETH to double their collateral value and then mint DSC tokens over the limit (breaking the protocol's health factor invariant).
As a result, the DSCEngine
contract will eventually be insolvent, and the DSC token will then be depegged to $0.
Manual Review
To fix the vulnerability, I recommend adding the require(s_priceFeeds[tokenAddresses[i]] == address(0), "Collateral token was already set");
to guarantee that there could not be any token ever registered twice.
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.