Pieces Protocol

First Flight #32
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: high
Valid

[H-5] Missing ability to delete open sell orders

Summary

The TokenDivider contract allows users to create sell orders for ERC20 tokens representing fractionalized NFTs. However, there is no mechanism for users to delete or cancel open orders. This limitation forces users to purchase their own order if they wish to recover the tokens, which may not always be feasible. If the user cannot afford the price set for the order because of the fees, the associated ERC20 tokens are effectively locked, preventing the user from reclaiming the underlying NFT. This can lead to the permanent loss of the NFT if the user cannot reacquire the fractional tokens.


Vulnerability Details

  1. No Order Deletion Functionality:

    • Once a sell order is created via the sellErc20 function, there is no way to cancel or delete the order, even if it was created by mistake or the user changes their mind.

  2. Tokens Are Locked in the Contract:

    • The ERC20 tokens tied to the sell order are transferred to the marketplace contract, preventing the user from reclaiming them unless they buy back the order.

  3. Self-Purchase Required:

    • To recover the ERC20 tokens, users must buy their own order by paying the price they set, including fees. If the user cannot afford this, the tokens remain locked, making it impossible to reclaim the NFT.

  4. Loss of NFT Due to Pricing Errors:

    • If the sell order is created with an unreasonably high price and the user lacks the funds to purchase the order, the user effectively loses access to the fractional tokens and the NFT itself.


Impact

  • Permanent Loss of NFT:

    • Users may permanently lose access to their NFTs if they cannot reacquire the ERC20 tokens due to financial constraints.

  • User Frustration:

    • The inability to cancel or update open orders can lead to a poor user experience, particularly in cases of accidental order creation.

  • Financial Loss:

    • Users are forced to pay transaction fees and protocol fees to buy back their own tokens, adding unnecessary costs.


Recommendations

  1. Add a cancelOrder Function:

    • Implement a function to allow users to cancel their own sell orders. This function should return the locked ERC20 tokens back to the user and remove the order from the marketplace.

    • Example implementation:

      function cancelOrder(uint256 orderIndex) external {
      SellOrder memory order = s_userToSellOrders[msg.sender][orderIndex];
      // Validate that the caller is the owner of the order
      if (order.seller != msg.sender) revert TokenDivider__Unauthorized();
      // Transfer the tokens back to the user
      balances[msg.sender][order.erc20Address] += order.amount;
      // Remove the order from the user's orders
      s_userToSellOrders[msg.sender][orderIndex] = s_userToSellOrders[msg.sender][s_userToSellOrders[msg.sender].length - 1];
      s_userToSellOrders[msg.sender].pop();
      emit OrderCancelled(msg.sender, order.erc20Address, order.amount);
      IERC20(order.erc20Address).transfer(msg.sender, order.amount);
      }
  2. Emit a OrderCancelled Event:

    • Emit an event when an order is successfully canceled to ensure transparency:

      event OrderCancelled(address indexed seller, address indexed erc20Address, uint256 amount);
Updates

Lead Judging Commences

fishy Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Sell orders cant be canceled

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.