Pieces Protocol

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

[L-1] Potential Reentrancy in `buyOrder` Function

Description

The buyOrder function makes Ether transfers to the seller and the contract owner (for fees) before finalizing some of the state changes. Even though no immediate harmful reentrancy scenario seems possible with the current logic (since user balances are updated before the external call, and the external calls are simple Ether transfers), it is considered a best practice to protect all externally-facing functions involving state changes and Ether transfers with a reentrancy guard.

By not using a reentrancy guard (or similar pattern, such as checks-effects-interactions) to prevent potential re-entrancy, the function technically allows for an attacker-supplied fallback to be executed during the Ether transfer, potentially opening the door for future vulnerabilities if additional logic is introduced or if other code changes inadvertently expose reentrant paths.


Impact

  • Potential Future Exploits:
    While there is no direct exploit apparent today, changes or extensions to the code in the future might inadvertently introduce exploitable conditions (e.g., if new state-modifying calls or logic are added before or after Ether transfers).

  • Best Practice Violation:
    A missing reentrancy guard contravenes widely accepted best practices for smart contracts, particularly in functions that handle Ether transfers.


Recommended Mitigation

  1. Use a Reentrancy Guard
    Import and inherit from OpenZeppelin’s ReentrancyGuard (or a similar mechanism). Then, apply the nonReentrant modifier to buyOrder (and other functions that handle external transfers):

    contract TokenDivider is ReentrancyGuard {
    // ...
    function buyOrder(uint256 orderIndex, address seller)
    external
    payable
    nonReentrant
    {
    // ...
    }
    // ...
    }
  2. Adhere to Checks-Effects-Interactions

    • Confirm all internal state updates happen before any external calls.

    • Avoid complex logic after the external call, so that any reentrant callback cannot overwrite critical state transitions.

By adopting a reentrancy guard, the contract follows established security patterns and protects against potential future reentrancy vulnerabilities—even if one does not currently appear exploitable.

Updates

Lead Judging Commences

fishy Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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