15,000 USDC
View results
Submission Details
Severity: high

The user can prevent his liquidation

Summary

The protocol currently uses any that has a chainlink price feed. Some tokens (e.g. USDC, USDT) have a contract level admin controlled address blacklist. If an address is blocked, then transfers to and from that address are forbidden.

Vulnerability Details

In DSCEngine.sol we have liquidate() function:

function liquidate(address collateral, address user, uint256 debtToCover)
external
moreThanZero(debtToCover)
nonReentrant
{
// need to check health factor of the user
uint256 startingUserHealthFactor = _healthFactor(user);
if (startingUserHealthFactor >= MIN_HEALTH_FACTOR) {
revert DSCEngine__HealthFactorOk();
}
// We want to burn their DSC "debt"
// And take their collateral
// Bad User: $140 ETH, $100 DSC
// debtToCover = $100
// $100 of DSC == ??? ETH?
// 0.05 ETH
uint256 tokenAmountFromDebtCovered = getTokenAmountFromUsd(collateral, debtToCover);
// And give them a 10% bonus
// So we are giving the liquidator $110 of WETH for 100 DSC
// We should implement a feature to liquidate in the event the protocol is insolvent
// And sweep extra amounts into a treasury
// 0.05 * 0.1 = 0.005. Getting 0.055
uint256 bonusCollateral = (tokenAmountFromDebtCovered * LIQUIDATION_BONUS) / LIQUIDATION_PRECISION;
uint256 totalCollateralToRedeem = tokenAmountFromDebtCovered + bonusCollateral;
_redeemCollateral(user, msg.sender, collateral, totalCollateralToRedeem);
// We need to burn the DSC
_burnDsc(debtToCover, user, msg.sender);
uint256 endingUserHealthFactor = _healthFactor(user);
if (endingUserHealthFactor <= startingUserHealthFactor) {
revert DSCEngine__HealthFactorNotImproved();
}
_revertIfHealthFactorIsBroken(msg.sender);
}

USDC has a contract level admin controlled address blocklist, which will block transfer to/from these blocked addresses.

If a user uses collateral that is a blacklisted address by USDC, it cannot be liquidated. This is because the transfer functors in _redeemCollateral and _burnDsc() in liquidate() will revert.

Impact

As the protocol is not able to fully liquidate such USDC-blocked addresses, it will incur bad debts and suffer losses.

Tools Used

Visual Studio Code

Recommendations

Try to implement a try-catch solution where you skip certain funds whenever they cause the USDC transfer to revert or use pull over push model to transfer tokens.

Support

FAQs

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