From 2bde8bfbb6ae48218318573ccb98436918ee16d9 Mon Sep 17 00:00:00 2001
From: bt3gl <1130416+bt3gl@users.noreply.github.com>
Date: Sat, 17 Sep 2022 17:55:39 -0700
Subject: [PATCH] Add a simple example for reentrancy and solutions with mutex
or CEI
---
Smart-Contract-Security/reentrancy-notes.md | 73 ++++++++++++++++++++-
1 file changed, 72 insertions(+), 1 deletion(-)
diff --git a/Smart-Contract-Security/reentrancy-notes.md b/Smart-Contract-Security/reentrancy-notes.md
index 3f356e4..3200419 100644
--- a/Smart-Contract-Security/reentrancy-notes.md
+++ b/Smart-Contract-Security/reentrancy-notes.md
@@ -3,12 +3,83 @@
+### TL; DR
+
* When a contract calls an external function, that external function may itself call the calling function.
+* A reentrancy attack may occur when a function makes an external call to another untrusted contract. Then, the unstrusted contract makes a recursive callback to the vulnerable contract function to steal funds.
* To prevent this attack, a contract can implement a lock in storage that prevents re-entrant calls.
+
-### References to learn about reentrancy
+---
+
+### Example of re-entrancy attack
+
+
+
+For example, suppose this method:
+
+```
+function withdrawBalance() public {
+ uint amountToWithdraw = userBalances[msg.sender];
+ (bool success, ) = msg.sender.call.value(amountToWithdraw)("");
+ requires(success);
+ userBalances[msg.sender] = 0;
+}
+```
+
+and this exploit:
+
+```
+function() public payable {
+ if(msg.sender == address(vulnContract)) {
+ vulnContract.withdrawBalance();
+ }
+}
+```
+
+How to fix?
+
+#### Option 1: Adding a mutex locking:
+
+```
+modifier noReentrant() {
+ require(!locked, "nooooope");
+ locked = true;
+ _;
+ locked = false;
+}
+```
+
+so
+
+```
+function withdrawBalance() public noReentrant {
+ ...
+}
+```
+
+
+
+#### Option 2: CEI (checks effects interaction) pattern
+
+```
+function withdrawBalance() public {
+ uint amountToWithdraw = userBalances[msg.sender];
+ userBalances[msg.sender] = 0; // update state first
+ (bool success, ) = msg.sender.call.value(amountToWithdraw)("");
+ requires(success);
+}
+```
+
+
+
+
+----
+
+
+### Resources