# Ataque de reentrância (Reentrancy attack)

O ataque de reentrância foi responsável por diversos hacks, incluindo o da DAO em 2016. Esse tipo de ataque ocorre quando um contrato realiza uma chamada externa para um endereço não confiável sem antes modificar seu próprio estado. O contrato malicioso pode então invocar recursivamente a função vulnerável. Por exemplo, uma função de saque que envia ETH antes de atualizar o saldo do usuário pode ser explorada se o endereço do destinatário for um contrato com uma função fallback que chame novamente a função de saque.

**Exemplo:** Vamos ver um exemplo onde um ataque de reentrância é possível.

```solidity
//Mala práctica
function withdraw() public {
		uint amount = balances[msg.sender];
		msg.sender.transfer(amount);
		balances[msg.sender] = 0;
}
```

Neste exemplo, usando a função `withdraw()`, um usuário pode sacar seu saldo em ether, o mesmo que foi previamente depositado no contrato. A função lê o saldo do usuário, envia o valor correspondente em ether para o endereço que realizou a chamada e, por fim, redefine o saldo desse endereço.

Como sabemos, é possível criar uma função *fallback* que receba ether e execute determinado código. Assim, um atacante pode implantar um contrato que inclua uma função *fallback* do seguinte tipo:

```solidity
//Código usado por un atacante 
address attackedAddress = 0x1234;
 function attack() public onlyOwner {
    attackedAddress.withdraw();
}
 function() external payable {
    while(attackedAddress.balance > 0) {
        attackedAddress.withdraw();
    }
}
```

No contrato anterior, `attackedAddress` é o endereço do contrato que contém ether e que será alvo do ataque. Um invasor pode implantar esse contrato e iniciar um ataque utilizando a função `attack()`, que drenará todos os fundos do contrato vulnerável.

**Mitigação:**

* Utilizar o padrão de "Retirada" (*withdraw pattern*) em vez do padrão de "Envio" (*send pattern*).
* Atualizar o estado interno antes de realizar chamadas externas.
* Limitar o uso de chamadas externas e utilizar bibliotecas de segurança, como a OpenZeppelin.

**Referência:**

* [OpenZeppelin ReentrancyGuard](https://docs.openzeppelin.com/contracts/4.x/api/security#ReentrancyGuard)


---

# 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://edp.ethkipu.org/modulo-5/seguridad-pruebas-y-auditoria/seguridad/principales-vulnerabilidades-en-smart-contracts/reentrancy-attack-ataque-de-reentrada.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.
