Pieces Protocol

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

Re-Entrancy Risk in `buyOrder`

Description

In the buyOrder function, Ether is sent to the seller via a low-level call:

(bool success, ) = payable(order.seller).call{value: (order.price - sellerFee)}("");

Without a re-entrancy guard (e.g., nonReentrant), a malicious seller could craft a fallback function to re-enter buyOrder or other state-changing functions in TokenDivider before state changes are fully finalized.

Impact

  1. Double Purchase or Double Withdraw: A malicious seller could re-enter in the middle of the Ether transfer to alter order data or cause unexpected results (e.g., re-purchasing tokens they just sold).

  2. Draining Funds: If combined with other state inconsistencies, the attacker could cause the contract to make multiple payments or incorrectly update balances.

Attack Route

  1. Malicious seller publishes a sell order with a specially crafted fallback function.

  2. msg.sender calls buyOrder, triggers the Ether call{value: ...}, which in turn calls the fallback function of the seller’s contract.

  3. In the fallback, the malicious code calls back into buyOrder (or another function) to modify state or create new orders, leading to inconsistent state or multiple Ether transfers.

Recommendation

  • Use OpenZeppelin’s ReentrancyGuard or a custom nonReentrant modifier to prevent re-entrancy in external-facing, state-changing functions:

    contract TokenDivider is IERC721Receiver, Ownable, ReentrancyGuard {
    // ...
    function buyOrder(uint256 orderIndex, address seller) external payable nonReentrant {
    // ...
    }
    }
  • Re-organize code to follow the Checks-Effects-Interactions pattern:

    1. Validate inputs

    2. Update state

    3. Interact with external contracts (Ether transfer, ERC20 transfers, etc.) last

Updates

Lead Judging Commences

juan_pedro_ventu Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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