code-423n4 / 2023-12-particle-findings

2 stars 1 forks source link

borrower can prevent liquidity provider from withdrawing their liquidity #42

Closed c4-bot-5 closed 9 months ago

c4-bot-5 commented 9 months ago

Lines of code

https://github.com/code-423n4/2023-12-particle/blob/main/contracts/protocol/ParticlePositionManager.sol#L170-L173

Vulnerability details

Description

When a liquidity provider wants to withdraw their liquidity they can call ParticlePositionManager::reclaimLiquidity. This will prevent any renewals:

ParticlePositionManager::addPremium:

File: protocol/ParticlePositionManager.sol

508:        // check LP allows extension of this lien
509:        if (lps.getRenewalCutoffTime(lien.tokenId) > lien.startTime) revert Errors.RenewalDisabled();

getRenewalCutoffTime is however never checked when opening a new position.

Hence a borrower can instead of renewing by adding premium simply close their position and open a new one. Since this opens a new loan with a new lien.startTime there's nothing the liquidity provider can do to prevent this.

Impact

A borrower can prevent a liquidity provider from withdrawing their liquidity by closing and opening a new position.

Proof of Concept

PoC test, can be added to ClosePosition.t.sol:

    function testStopWithdrawLiquidity() public {
        _openLongPosition();

        // LP decides to withdraw their liquidity
        vm.prank(LP);
        particlePositionManager.reclaimLiquidity(_tokenId);

        vm.warp(block.timestamp + LOAN_TERM - 1);

        // borrower doesn't want that and can continue borrowing liquidity
        // by closing then opening a new position against same LP position
        _closeLongPosition(0, true, true);
        _openLongPosition();

        // 1 second after loan term
        vm.warp(block.timestamp + 2);

        // LP cannot claim all of their liquidity
        vm.prank(LP);
        vm.expectRevert();
        particlePositionManager.decreaseLiquidity(_tokenId, _liquidity);
    } 

Tools Used

Manual audit

Recommended Mitigation Steps

Consider blocking openPosition if renewalCutoffTime is set to allow a liquidity provider to completely withdraw.

Assessed type

DoS

c4-judge commented 9 months ago

0xleastwood marked the issue as primary issue

c4-judge commented 9 months ago

0xleastwood marked the issue as duplicate of #35

c4-judge commented 8 months ago

0xleastwood marked the issue as satisfactory