Back to Blog

Secure Smart Contract Development — Code Reentrancy in NFT Contracts

Code Auditing
August 5, 2022

Introduction

Given the prosperity of NFT ecosystem on Ethereum and the increase of related security issues, we will post a series of blogs to introduce these security issues and give some suggestions for developers to secure contracts. In this blog, we will introduce the reentrancy issue in NFT contracts and how to mitigate the related vulnerability.

What is Reentrancy

According to wikipedia

In computing, a computer program or subroutine is called reentrant if multiple invocations can safely run concurrently on multiple processors, or on a single processor system, where a reentrant procedure can be interrupted in the middle of its execution and then safely be called again (“re-entered”) before its previous invocations complete execution.

In a smart contract, reentrancy can occur when a function executes an external call of another contract, which further invokes the original function (or other functions) before the original invocation returns. If the external call is controlled by an untrusted entity (e.g., a malicious contract), it can lead to an unexpected result. That’s because, in some functions, the result depends on the contract state. The contract state will be updated after the external call. However, the reentrant invocation of the function will use the old state instead of the updated one.

Reentrancy has been a prevalent issue in smart contracts, e.g., the MakerDAO attack, the ERC777 on Uniswap, and others (search Reentrancy on BlockSec Academy).

Reentrancy in NFT

For NFT contracts, there exist some implicit external function calls that could be neglected by developers. They include onERC721Received and onERC1155Received function. The onERC721Received function was designed to check whether the receiver contract can handle NFTs (to prevent the NFTs from being locked forever.) This function is invoked in the safeTransferFrom and _safeMint of the ERC721 contract. The similar one exists in the ERC1155 contract. Due to these external function calls, the reentrancy could happen without being noticed by contract developers.

Single-Function Reentrancy

The single-function reentrancy is the simpler form of reentrancy attack. In this kind of reentrancy attack, the re-invoked function is same with the original function. An attacker can invoke the function repeatedly before the first invocation of the function is completed. In NFT contracts, this usually happens in the functions related to the mint operation.

For instance, some NFT projects may give each user a chance to mint NFT freely, set the maximum supply of the whole project, or set the maximum amount of NFTs one user can hold. Usually, these constraints are checked before the actual mint operation. But if the states related to these constraints are updated after the safeMint function, the attacker can reenter this mint function and bypass the constraints since the related states are the same as the first invocation of this function. The HypeBears reentrancy attack posted in our previous blog is an example.

A more complicated single-function reentrancy occurs when safeMint function is used in a loop and the constraints are checked before the loop starts. In this scenario, even some states will be updated automatically before the external call, the remaining safeMint function calls in the loop can still bypass the validation since the loop has already started and the validation happens before the loop starts.

For instance, in the example shown in another post, the mintNFT function will check if the number of NFTs the user wants to mint plus the current supply can exceed the max supply. The safeMint function updates the total supply before the onERC721Received external call. An attacker can still exploit it since the safeMint function only increases the total supply by 1 each time. So if the attacker re-enter the mintNFT function in the first function call of safeMint in the loop, the total supply becomes old supply plus 1, instead of old supply plus the amount of NFTs that will be minted by the first call of mintNFT.

Cross-Function Reentrancy

Instead of entering the same function, the attacker can enter another function that shares or depends on the states with the origin function. We have detailed some cases in our previous blogs for the Revest case and the OMNI case.

Summary and Suggestions

Here are some suggestions for NFT smart contract developers to mitigate the reentrancy threat.

  1. Use the Checks-Effects-Interactions Pattern in your code.
  2. Be careful when you use any third-part library that will introduce external calls. For NFT contracts, be cautious with the implicit callback of onERC721Received and onERC1155Received function.

Read the Other Article in This Series

About BlockSec

BlockSec is a pioneering blockchain security company established in 2021 by a group of globally distinguished security experts. The company is committed to enhancing security and usability for the emerging Web3 world in order to facilitate its mass adoption. To this end, BlockSec provides smart contract and EVM chain security auditing services, the Phalcon platform for security development and blocking threats proactively, the MetaSleuth platform for fund tracking and investigation, and MetaSuites extension for web3 builders surfing efficiently in the crypto world.

To date, the company has served over 300 esteemed clients such as MetaMask, Uniswap Foundation, Compound, Forta, and PancakeSwap, and received tens of millions of US dollars in two rounds of financing from preeminent investors, including Matrix Partners, Vitalbridge Capital, and Fenbushi Capital.

Official website: https://blocksec.com/

Official Twitter account: https://twitter.com/BlockSecTeam

Sign up for the latest updates
~$418M Lost: Bitget, NEAR Intents Exploits | BlockSec Weekly
Security Insights

~$418M Lost: Bitget, NEAR Intents Exploits | BlockSec Weekly

This biweekly security report records eight incidents from September 21 to October 4, 2026, with approximately $418.4M in losses across Ethereum, BNB Chain, Solana, Bitcoin, TRON, XRP Ledger, Zcash, Avalanche, NEAR, and related networks. Detailed analysis covers Bitget's $387.5M third-party security product vulnerability and NEAR Intents' $3.87M refund validation flaw and missing state rollback.

Bitget's $387.5M Off-Chain Breach: Beyond Keys and Contracts
Security Insights

Bitget's $387.5M Off-Chain Breach: Beyond Keys and Contracts

On September 24, 2026, attackers exploited a vulnerability in a third-party security product, obtained internal credentials, and forged withdrawal commands. The resulting transfers moved approximately $387.5M from some of Bitget's operational wallets across Ethereum, other EVM networks, XRP Ledger, Zcash, and TRON; private keys and cold wallets remained intact. This deep dive summarizes the disclosed incident path and fund flow, examines rapid conversion into native assets and the ecosystem recovery response, proposes a systematic defense-in-depth framework for institutions, and explains how authorized blockchain penetration testing can validate cross-layer assumptions.

~$11.3M Lost: Multicall Router, Nostra | BlockSec Weekly
Security Insights

~$11.3M Lost: Multicall Router, Nostra | BlockSec Weekly

This report, covering 2026/09/14 - 2026/09/20, examines two security incidents with approximately $11.3M in combined losses, on Ethereum and Starknet. In the larger one, a multicall router accepted its own address as a dispatch target, so the nested call reached the Gateway module of a Safe wallet carrying the router's own already-authorized identity instead of the external caller's, and roughly 2,900 `aEthrsETH` was routed out of that wallet into an attacker-created Uniswap v4 pool. On Starknet, Nostra's oracle integration required a minimum of only one aggregated source, so when only two of the three configured price sources reached the aggregation, a manipulated thin-pool quote averaged with a normal quote to value `NSTR` at roughly $49.52, supporting approximately $3.5M of borrowing against overvalued collateral.

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit