# Preventing Reentrancy When Using SafeERC721

The `SafeERC721` library from OpenZeppelin is often used to ensure the safe transfer of ERC-721 tokens by verifying that contracts correctly implement the `onERC721Received` interface. However, **this does not automatically protect against reentrancy attacks**. The use of `onERC721Received` creates an external call to the recipient contract, which opens a potential reentrancy attack vector if the recipient contract is malicious or incorrectly implemented.

This tutorial focuses on how reentrancy vulnerabilities can arise when using `SafeERC721` and what precautions to take to ensure your contracts are secure.

***

#### Understanding `SafeERC721` and Reentrancy

OpenZeppelin's `SafeERC721` provides a safer way to transfer non-fungible tokens (NFTs) by ensuring that the recipient contract implements the `IERC721Receiver` interface. The key point of vulnerability lies in the **`onERC721Received` hook**. When transferring a token using `safeTransferFrom`, the transfer process checks whether the recipient is a contract. If it is, the contract must implement the `onERC721Received` function.

Here’s a simplified version of how `safeTransferFrom` works:

```solidity
solidityCopy codefunction safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes memory data
) public {
    _transfer(from, to, tokenId);

    if (to.isContract()) {
        require(
            IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, data) ==
            IERC721Receiver.onERC721Received.selector,
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }
}
```

After the token is transferred, the contract calls `onERC721Received` on the recipient. This is where the risk of **reentrancy** comes into play.

***

#### The Risk of Reentrancy in `onERC721Received`

The **`onERC721Received`** hook is executed by the recipient contract after the token transfer is initiated. A malicious contract could use this function to perform reentrant calls, such as calling back into the original contract and executing additional operations before the original transaction has finished processing. This can result in the contract being in an inconsistent state and exploited by the attacker.

`onERC721Received` function is used to re-enter the original contract and perform an additional `call` before the first transfer completes. If your contract doesn’t guard against reentrancy, it could allow an attacker to transfer tokens multiple times or manipulate the contract’s state.

***

#### How to Prevent Reentrancy When Using `SafeERC721`

To protect against reentrancy attacks when using `SafeERC721`, you need to:

1. **Use OpenZeppelin's `ReentrancyGuard` modifier**: This prevents functions from being called recursively during the execution of a transaction.
2. **Update state variables before making external calls**: Always update the contract's state before calling `safeTransferFrom` or any other external function to avoid having an outdated state during a reentrancy attempt.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zokyo-auditing-tutorials.gitbook.io/zokyo-tutorials/tutorial-65-erc721-and-nfts/preventing-reentrancy-when-using-safeerc721.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
