code-423n4 / 2022-11-paraspace-findings

7 stars 4 forks source link

WPunk will become locked if liquidator ops to receive the underlying token instead of nToken #494

Closed code423n4 closed 1 year ago

code423n4 commented 1 year ago

Lines of code

https://github.com/code-423n4/2022-11-paraspace/blob/c6820a279c64a299a783955749fdc977de8f0449/paraspace-core/contracts/ui/WPunkGateway.sol#L102-L117

Vulnerability details

Impact

WPunks received directly as the result of liquidation will be unable to be withdrawn

Proof of Concept

function withdrawPunk(uint256[] calldata punkIndexes, address to)
    external
    nonReentrant
{
    INToken nWPunk = INToken(
        Pool.getReserveData(address(WPunk)).xTokenAddress
    );
    for (uint256 i = 0; i < punkIndexes.length; i++) {
        nWPunk.safeTransferFrom(msg.sender, address(this), punkIndexes[i]);
    }
    Pool.withdrawERC721(address(WPunk), punkIndexes, address(this));
    for (uint256 i = 0; i < punkIndexes.length; i++) {
        WPunk.burn(punkIndexes[i]);
        Punk.transferPunk(to, punkIndexes[i]);
    }
}

When a user tries to withdraw a CryptoPunk from WPunkGateway it only works if the WPunk is wrapped in an nToken. When calling liquidateERC721 it allows the liquidator to specify whether they want to receive the collateral as an nToken or as the underlying. If the liquidator specifies that they want to receive it as an underlying they will receive the underlying WPunk. Since they now have a WPunk rather than an nWPUnk they cannot withdraw their CyptoPunk and it is frozen in WPunkGateway unable to be withdrawn.

Tools Used

Manual Review

Recommended Mitigation Steps

Create a secondary function that allows WPunks to be withdrawn directly or block liquidators from being able to select to receive the underlying for WPunks.

c4-judge commented 1 year ago

dmvt marked the issue as primary issue

c4-judge commented 1 year ago

dmvt marked the issue as unsatisfactory: Invalid