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

3 stars 3 forks source link

Should let liquidator seize the pending harvested reward and already harvested reward instead of letting original position nft owner who failed to pay the debt claim the reward #6

Closed c4-bot-8 closed 10 months ago

c4-bot-8 commented 11 months ago

Lines of code

https://github.com/code-423n4/2023-12-initcapital/blob/a53e401529451b208095b3af11862984d0b32177/contracts/core/PosManager.sol#L265 https://github.com/code-423n4/2023-12-initcapital/blob/a53e401529451b208095b3af11862984d0b32177/contracts/core/PosManager.sol#L308 https://github.com/code-423n4/2023-12-initcapital/blob/a53e401529451b208095b3af11862984d0b32177/contracts/core/PosManager.sol#L292 https://github.com/code-423n4/2023-12-initcapital/blob/a53e401529451b208095b3af11862984d0b32177/contracts/core/InitCore.sol#L347

Vulnerability details

Impact

Should let liquidator seize the pending harvested reward and already harvested reward instead of letting original position nft owner who failed to pay the debt claim the reward

Proof of Concept

if user collateralize using WLP

and then decollateralize to remove WLP

the code will harvest the reward, then the nft position can claim the reward

all these logic is in the function removeCollateralWLPTo and calling _harvest

the logic to harvest reward is here

 function _harvest(uint _posId, address _wlp, uint _tokenId) internal {
        (address[] memory tokens, uint[] memory amts) = IBaseWrapLp(_wlp).harvest(_tokenId, address(this));
        for (uint i; i < tokens.length; i = i.uinc()) {
            pendingRewards[_posId][tokens[i]] += amts[i];
        }
    }

then position owner can call claimPendingRewards to claim the harvested reward

while this approach ensures that the orignial LP owner can have access to the pending reward (such as fee as liquidity provider)

the problem is that the same function removeCollateralWLPTo is used to transfer the WLP to the liquidator

// reduce and burn wLp to underlying for liquidator
lpAmtOut = IPosManager(POS_MANAGER).removeCollateralWLpTo(_posId, _wLp, _tokenId, wLpAmtToBurn, msg.sender);

so during liquidation flow, the liqudiator still help original position owner that has bad debt to harvest pending reward and then even when the WLP is liquidated,

but the pending reward and harvested reward goes to the original nft position which failed to repay the debt instead of the liquidator who help repay the debt

in the case when there are bad debt, and the left WLP worth exceeds debt,

liquidator will have less incentive to repay the debt because the code does not send pending harvested reward and already harvested reward to liqudiator

Tools Used

Manual Review

Recommended Mitigation Steps

send pending harvested reward and already harvested reward to liqudiator when the user's position is liquidated

Assessed type

Token-Transfer

c4-judge commented 10 months ago

hansfriese marked the issue as primary issue

c4-sponsor commented 10 months ago

fez-init (sponsor) disputed

fez-init commented 10 months ago

Collateral credit does not take into account the harvestable rewards, so the liquidator should not get these rewards as well.

c4-judge commented 10 months ago

hansfriese marked the issue as unsatisfactory: Invalid