Root Cause: The listNFT function in the BidBeastsNFTMarket contract violates the Checks-Effects-Interactions (CEI) pattern by performing an external call to BBERC721.transferFrom before updating internal state. The CEI pattern requires that all state changes (effects) occur after checks and before external interactions to prevent reentrancy attacks. The current implementation makes the external call first, leaving the contract vulnerable to reentrancy if the called contract (e.g., a malicious ERC-721 token) reenters the function.
Impact: This violation exposes the contract to potential reentrancy attacks, where a malicious ERC-721 contract could reenter listNFT or other functions, leading to double listings, inconsistent state, or NFT loss. While the impact is limited by the low severity and specific conditions required for exploitation, it could disrupt marketplace operations and erode user trust if exploited.
This violates the Checks-Effects-Interactions (CEI) pattern, which dictates that all state changes should occur before making external calls. Failing to follow CEI can allow malicious contracts to exploit reentrancy during the external call.
Checks – validate inputs and conditions.
Effects – update internal state.
Interactions – make external calls only after state updates.
The BidBeastsNFTMarket::listNFT function transfers an NFT to the contract using:
Likelihood: Low. The vulnerability requires a malicious ERC-721 token contract to be used, which depends on the seller interacting with a compromised or attacker-controlled NFT. This scenario is uncommon but possible in an open marketplace where users may list NFTs from untrusted sources.
Impact: Low. The impact is limited to specific reentrancy scenarios, with potential for state inconsistencies or NFT loss, but it does not inherently cause direct financial loss unless exploited in combination with other vulnerabilities. The primary risk is operational disruption and reduced trust.
The vulnerability arises from the CEI pattern violation, where the external call to BBERC721.transferFrom precedes state updates, creating a reentrancy risk. This can be explained as follows:
Reentrancy Opportunity: When BBERC721.transferFrom is called, a malicious ERC-721 contract can implement onERC721Received to reenter listNFT before the listings[tokenId] update. During this reentry, the attacker could call listNFT again with the same tokenId, potentially overwriting the listings mapping or triggering unintended behavior, such as listing the NFT multiple times under different parameters.
State Inconsistency: If reentrancy occurs, the listings[tokenId] might not reflect the intended seller, minPrice, or buyNowPrice from the original call, leading to an inconsistent state. For example, an attacker could set a lower minPrice or a different seller, disrupting the auction process.
NFT Loss Risk: In extreme cases, a malicious contract could manipulate the transfer logic or reenter to transfer the NFT elsewhere before the state is updated, though this depends on the specific ERC-721 implementation and additional vulnerabilities.
Importance of CEI: The CEI pattern prevents such issues by ensuring state changes are finalized before external calls, making reentrancy ineffective. The current order allows the external call to act as a gateway for reentry, highlighting the need to reorder the logic to align with best practices.
This proof demonstrates that the lack of CEI adherence creates a subtle but exploitable weakness, particularly in an open marketplace where NFT sources may vary.
Refactor listNFT to update internal state before performing external calls:
Solidity Security Patterns – Checks-Effects-Interactions (CEI)
Official guide on the CEI pattern and reentrancy mitigation.
Consensys Best Practices – Reentrancy
Detailed explanation of the CEI pattern to avoid reentrancy attacks.
https://consensys.github.io/smart-contract-best-practices/known_attacks/#reentrancy
OWASP Smart Contract Security Cheat Sheet
Includes guidance on using CEI for safe external calls.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.