code-423n4 / 2022-06-putty-findings

5 stars 0 forks source link

withdraw of assets batch could be blocked with one asset with malicious code #349

Closed code423n4 closed 2 years ago

code423n4 commented 2 years ago

Lines of code

https://github.com/code-423n4/2022-06-putty/blob/main/contracts/src/PuttyV2.sol#L466-L520 https://github.com/code-423n4/2022-06-putty/blob/main/contracts/src/PuttyV2.sol#L636-L661

Vulnerability details

Impact

withdraw() function calls internal functions that tranfers assets - _transferERC20sOut, _transferERC721sOut, _transferFloorsOut. They could only run through all transferring assets in one cycle. If one of transferring assets has malicious code that blocks all transfers, except those allowed by an attacker, then an attacker could demand a ransom from the victim for allowing the withdrawal of blocked assets.

    /**
        @notice Transfers an array of erc20 tokens to the msg.sender.
        @param assets The erc20 tokens and amounts to send.
     */
    function _transferERC20sOut(ERC20Asset[] memory assets) internal {
        for (uint256 i = 0; i < assets.length; i++) {
            ERC20(assets[i].token).safeTransfer(msg.sender, assets[i].tokenAmount);
        }
    }

    /**
        @notice Transfers an array of erc721 tokens to the msg.sender.
        @param assets The erc721 tokens and token ids to send.
     */
    function _transferERC721sOut(ERC721Asset[] memory assets) internal {
        for (uint256 i = 0; i < assets.length; i++) {
            ERC721(assets[i].token).safeTransferFrom(address(this), msg.sender, assets[i].tokenId);
        }
    }

    /**
        @notice Transfers an array of erc721 floor tokens to the msg.sender.
        @param floorTokens The contract addresses for each floor token.
        @param floorTokenIds The token id of each floor token.
     */
    function _transferFloorsOut(address[] memory floorTokens, uint256[] memory floorTokenIds) internal {
        for (uint256 i = 0; i < floorTokens.length; i++) {
            ERC721(floorTokens[i]).safeTransferFrom(address(this), msg.sender, floorTokenIds[i]);
        }
    }

Proof of Concept

Example of attack:

Recommended Mitigation Steps

Add functionality that allows withdrawing specific assets apart from a batch.

outdoteth commented 2 years ago

Duplicate: Setting malicious or invalid erc721Assets, erc20Assets or floorTokens prevents the option from being exercised: https://github.com/code-423n4/2022-06-putty-findings/issues/50