Lucene search

K
code423n4Code4renaCODE423N4:2023-12-PARTICLE-FINDINGS-ISSUES-6
HistoryDec 17, 2023 - 12:00 a.m.

Liquidation is not possible if trader blacklisted from blacklistable ERC20 token

2023-12-1700:00:00
Code4rena
github.com
5
liquidation
blacklisted
erc20
token-transfer
vulnerability
uniswap
mitigation
profit
borrower
liquidity provider
position manager

6.9 Medium

AI Score

Confidence

Low

Lines of code

Vulnerability details

Impact

If a trader is blacklisted from a blacklistable ERC20 token while has an open position, it may not be possible to liquidate the position.

Proof of Concept

When liquidate position, it will eventually calculate the amount of token that need to be send to borrower, the amount will be non-zero if the position is profitable or the borrower has excess premium.

<https://github.com/code-423n4/2023-12-particle/blob/main/contracts/protocol/ParticlePositionManager.sol#L374&gt;

<https://github.com/code-423n4/2023-12-particle/blob/main/contracts/protocol/ParticlePositionManager.sol#L460-L490&gt;

    function _closePosition(
        DataStruct.ClosePositionParams calldata params,
        DataCache.ClosePositionCache memory cache,
        Lien.Info memory lien,
        address borrower
    ) internal {
        ...
        // calculate the the amounts owed to LP up to the premium in the lien
        // must ensure enough amount is left to pay for interest first, then send gains and fund left to borrower
        ///@dev refundWithCheck ensures actual cannot be more than expected, since amount owed to LP is in actual,
        ///     it ensures (1) on the collateralFrom part of refund, tokenOwed is covered, and (2) on the amountReceived
        ///      part, received is no less than liquidity addback + token owed.
        if (lien.zeroForOne) {
            cache.token0Owed = cache.token0Owed &lt; cache.tokenToPremium ? cache.token0Owed : cache.tokenToPremium;
            cache.token1Owed = cache.token1Owed &lt; cache.tokenFromPremium ? cache.token1Owed : cache.tokenFromPremium;
&gt;&gt;&gt;         Base.refundWithCheck(
                borrower,
                cache.tokenFrom,
                cache.collateralFrom + cache.tokenFromPremium,
                cache.amountSpent + cache.amountFromAdd + cache.token1Owed
            );
&gt;&gt;&gt;         Base.refundWithCheck(
                borrower,
                cache.tokenTo,
                cache.amountReceived + cache.tokenToPremium,
                cache.amountToAdd + cache.token0Owed
            );
        } else {
            cache.token0Owed = cache.token0Owed &lt; cache.tokenFromPremium ? cache.token0Owed : cache.tokenFromPremium;
            cache.token1Owed = cache.token1Owed &lt; cache.tokenToPremium ? cache.token1Owed : cache.tokenToPremium;
&gt;&gt;&gt;         Base.refundWithCheck(
                borrower,
                cache.tokenFrom,
                cache.collateralFrom + cache.tokenFromPremium,
                cache.amountSpent + cache.amountFromAdd + cache.token0Owed
            );
&gt;&gt;&gt;         Base.refundWithCheck(
                borrower,
                cache.tokenTo,
                cache.amountReceived + cache.tokenToPremium,
                cache.amountToAdd + cache.token1Owed
            );
        }

        // pay for interest
        lps.addTokensOwed(lien.tokenId, cache.token0Owed, cache.token1Owed);
    }

The issue with this design is that if a borrower is blacklisted from a blacklistable token, such as USDC, it will not be possible to send profits or excess premium back to the borrower.

This will not only impact the borrower but also the liquidity provider, as the token cannot be added back to the Uniswap V3 LP position.

Tools Used

Manual review

Recommended Mitigation Steps

use the “Pull over Push” design for sending profit/excess premium to the borrower.

Assessed type

Token-Transfer


The text was updated successfully, but these errors were encountered:

All reactions

6.9 Medium

AI Score

Confidence

Low