Zero amount token transfers may cause a denial of service during liquidations
mediumLines of code
Vulnerability details
Summary
Some ERC20 implementations revert on zero value transfers. Since liquidation rewards are based on a fraction of the available position's premiums, this may cause an accidental denial of service that prevents the successful execution of liquidations.
Impact
Liquidations in the LAMM protocol are incentivized by a reward that is calculated as a fraction of the premiums available in the position.
solidity348: // calculate liquidation reward 349: liquidateCache.liquidationRewardFrom = 350: ((closeCache.tokenFromPremium) * LIQUIDATION_REWARD_FACTOR) / 351: uint128(Base.BASIS_POINT); 352: liquidateCache.liquidationRewardTo = 353: ((closeCache.tokenToPremium) * LIQUIDATION_REWARD_FACTOR) / 354: uint128(Base.BASIS_POINT);
These amounts are later transferred to the caller, the liquidator, at the end of the liquidatePosition() function.
solidity376: // reward liquidator 377: TransferHelper.safeTransfer(closeCache.tokenFrom, msg.sender, liquidateCache.liquidationRewardFrom); 378: TransferHelper.safeTransfer(closeCache.tokenTo, msg.sender, liquidateCache.liquidationRewardTo);
Reward amounts, liquidationRewardFrom and liquidationRewardTo, can be calculated as zero if tokenFromPremium or tokenToPremium are zero, if the liquidation ratio gets rounded down to zero, or if LIQUIDATION_REWARD_FACTOR is zero.
Coupled with that fact that some ERC20 implementations revert on zero value transfers, this can cause an accidental denial of service in the implementation of liquidatePosition(), blocking certain positions from being liquidated.
Recommendation
Check that the amounts are greater than zero before executing the transfer.
diff// reward liquidator + if (liquidateCache.liquidationRewardFrom > 0) { TransferHelper.safeTransfer(closeCache.tokenFrom, msg.sender, liquidateCache.liquidationRewardFrom); + } + if (liquidateCache.liquidationRewardTo > 0) { TransferHelper.safeTransfer(closeCache.tokenTo, msg.sender, liquidateCache.liquidationRewardTo); + }
Assessed type
ERC20
