15,000 USDC
View results
Submission Details
Severity: medium
Valid

Collateral accounting is broken for fee-on-transfer tokens such as USDT

Summary

As per specs, wETH and wBTC should be interchangeable with other collateral that is supported by Chainlink, such as USDT. However, the logic for accounting for a user's deposited collateral defined in the depositCollateral function credits the user for an amount of collateral prior to the fee being taken out, for fee-on-transfer token collateral. Due to this, users will have an artificially inflated collateral value.

Vulnerability Details

The depositCollateral function is defined as follows:

function depositCollateral(address tokenCollateralAddress, uint256 amountCollateral)
public
moreThanZero(amountCollateral)
isAllowedToken(tokenCollateralAddress)
nonReentrant
{
s_collateralDeposited[msg.sender][tokenCollateralAddress] += amountCollateral;
emit CollateralDeposited(msg.sender, tokenCollateralAddress, amountCollateral);
bool success = IERC20(tokenCollateralAddress).transferFrom(msg.sender, address(this), amountCollateral);
if (!success) {
revert DSCEngine__TransferFailed();
}
}

The s_collateralDeposited amount credited to a user is equal to the amountCollateral, which is the amount which is fed in the transferFrom function call. However, this amount overstates the actual amount the DSCEngine contract will receive, which will be amountCollateral minus the fee. Therefore, the collateral balance for users will be inflated.

Impact

Users who deposit collateral for a token which is fee-on-transfer will have an over-inflated collateral value, meaning they can mint more DSC than they should, breaking the economic security of this protocol.

Tools Used

Manual review

Recommendations

The amount of collateral credited to a user should be equal to the difference in the balance of that token before and after the token is transferred to the DSCEngine contract.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.