codehawks-2023-07-dsc-h03

[H-03] There is no incentive to liquidate small positions

보고서

Summary

가스 비용보다 적은 소액의 담보는 청산해서 얻는 이익이 없으므로 방치될 수 있다. 이런 소액의 부실채권이 다수 남아 프로토콜을 잠식하면 프로토콜이 저담보 상태가 될 수 있다.

Keyword

business logic vul

Vulnerability

담보 토큰의 가격이 떨어져서 유저의 담보가 200% 과담보 아래로 떨어지면 아무나 liquidate 함수를 호출해 자신의 DSC 토큰을 소각하며 해당 유저(이하 유저A)의 담보를 청산할 수 있다. liquidate 함수 호출자는 소각한 DSC의 가치만큼의 담보 토큰을 얻으며 추가로 10%의 보너스 담보 토큰을 더 얻을 수 있다.

하지만 소액의 담보의 경우 청산 후 받는 담보보다 나가는 가스 비용이 더 나가므로 청산을 통해 받는 이득이 없다.

    function liquidate(address collateral, address user, uint256 debtToCover)
        external
        moreThanZero(debtToCover)
        nonReentrant
    {
        uint256 startingUserHealthFactor = _healthFactor(user);
        if (startingUserHealthFactor >= MIN_HEALTH_FACTOR) {
            revert DSCEngine__HealthFactorOk();
        }
 
        uint256 tokenAmountFromDebtCovered = getTokenAmountFromUsd(collateral, debtToCover);
 
        uint256 bonusCollateral = (tokenAmountFromDebtCovered * LIQUIDATION_BONUS) / LIQUIDATION_PRECISION;
        uint256 totalCollateralToRedeem = tokenAmountFromDebtCovered + bonusCollateral;
        _redeemCollateral(user, msg.sender, collateral, totalCollateralToRedeem);
        _burnDsc(debtToCover, user, msg.sender);
 
        uint256 endingUserHealthFactor = _healthFactor(user);
        if (endingUserHealthFactor <= startingUserHealthFactor) {
            revert DSCEngine__HealthFactorNotImproved();
        }
        _revertIfHealthFactorIsBroken(msg.sender);
    }

청산해도 이득이 없으므로 부실 채권이 청산되지 않을 것이며, 이런 소액의 부실채권이 다수 남아 프로토콜을 잠식하면 프로토콜이 저담보 상태가 될 수 있다.

Impact

프로토콜이 저담보 상태가 되어 유저가 DSC를 담보 토큰으로 바꿀 수 없게 되며, 이로 인해 자금이 완전히 손실될 수 있다.

Mitigation

잠재적인 해결 방법은 담보의 가치가 특정 임계값을 초과하는 경우에만 DSC를 발행할 수 있도록 제한을 두는 것이다.


tags: bughunting, codehawks, smart contract, solidity, business-logic-vul, severity high