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.
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
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.