Skip to content

Reentrancy via ERC721/1155 safe-Transfer Callback

SAFE-0147 Reentrancy Checked automatically by the scanner
1

What goes wrong

_safeMint / safeTransferFrom invokes onERC721Received / onERC1155Received on the recipient before the surrounding state is finalised. A malicious recipient re-enters (e.g. mints again below a per-wallet cap, or claims twice) during that callback.

2

The vulnerable pattern

proof of concept — how it is exploited
// mint(): _safeMint(msg.sender, id); minted[msg.sender]=true;
// attacker onERC721Received() { if(count<10) Victim.mint(); }
// re-enters before minted flag is set -> bypasses the 1-per-wallet cap.
3

How to fix it

the pattern that is safe
// checks-effects-interactions + guard around the safe-mint
function mint() external nonReentrant {
    require(!minted[msg.sender]); minted[msg.sender] = true;  // effects first
    _safeMint(msg.sender, id);                                 // interaction last
}
HypeBears / many NFT mints. CEI + nonReentrant around safeMint.
Check your own contract for this

The SaferICO scanner runs 201 detectors over your Solidity source, SAFE-0147 among them. Paste an address or the source itself — a small per-scan fee, shown before you sign, or unlimited on any plan.

Run the scanner See how it is attacked Read the docs