# Mitigating Read-Only Reentrancy

{% hint style="info" %}
[**Book an audit with Zokyo**](https://www.zokyo.io/)
{% endhint %}

In the landscape of smart contracts and decentralized finance (DeFi), a variety of exploits have been identified, including the read-only reentrancy attack. This type of attack reenters a view function that is typically unguarded due to its non-state-modifying nature, leading to potential unintended actions if the state is inconsistent. Below are strategies to help mitigate such vulnerabilities:

### 1. Recognize Vulnerable Patterns

Understanding the conditions under which read-only reentrancy attacks occur is the first step to prevention. A vulnerable situation typically arises when there is an external call to another contract before the state of the current contract is fully updated. Understanding this pattern can help developers in identifying potential risks during the design and development of their smart contracts.

### 2. Reentrancy Guards

While traditional reentrancy guards that block state-modifying functions are not applicable for read-only reentrancy, it is possible to employ a variant of these guards. Even if a function does not change the state, it should be protected from reentrancy if it is accessed during intermediate stages of a transaction before the contract’s state is fully updated. This can be achieved by using a semaphore that locks the contract state for the duration of a transaction, preventing reentry.

**Example:**

```
pragma solidity ^0.8.7;

contract ReentrancyGuard {
    bool internal _notEntered = true;

    modifier nonReentrant() {
        require(_notEntered, "ReentrancyGuard: reentrant call");
        _notEntered = false;
        _;
        _notEntered = true;
    }
}

contract MyContract is ReentrancyGuard {
    uint256 public balance = 0;

    function deposit() external payable nonReentrant {
        balance += msg.value;
    }

    function withdraw(uint256 amount) external nonReentrant {
        require(amount <= balance, "Insufficient funds");
        balance -= amount;
        payable(msg.sender).transfer(amount);
    }
}

```

In the above code, the `nonReentrant` modifier ensures that while a function with this modifier is being executed, it can't be called again until it finishes, preventing reentrancy.

### 3. Use of Checks-Effects-Interactions Pattern

Follow the Checks-Effects-Interactions pattern to prevent reentrancy attacks. This pattern ensures that the state of the contract is updated before interacting with external contracts. Any state variables that affect execution flow or can be accessed through external calls should be updated prior to those calls.

1. **Checks**: Perform all the checks (e.g., `require` statements).
2. **Effects**: Update any state variables.
3. **Interactions**: Interact with other contracts.

By following this order, even if a called contract attempts a reentrancy attack, the state of the original contract will already be updated, rendering the attack ineffective.


---

# 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-9-read-only-reentrancy/mitigating-read-only-reentrancy.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.
