mirror of
https://github.com/autistic-symposium/blockchains-security-toolkit.git
synced 2025-09-27 03:30:50 -04:00
🥓 clean up
This commit is contained in:
parent
68066e2c89
commit
ef50ffba5a
27 changed files with 0 additions and 0 deletions
89
smart_contracts_vulnerabilities/reentrancy-notes.md
Normal file
89
smart_contracts_vulnerabilities/reentrancy-notes.md
Normal file
|
@ -0,0 +1,89 @@
|
|||
## Reentrancy
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
### 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.
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
---
|
||||
|
||||
### Example of re-entrancy attack
|
||||
|
||||
<br>
|
||||
|
||||
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 {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
#### 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);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
----
|
||||
|
||||
|
||||
### Resources
|
||||
|
||||
<br>
|
||||
|
||||
* [Solidity docs](https://docs.soliditylang.org/en/latest/security-considerations.html#re-entrancy)
|
||||
* [DASP](https://www.dasp.co/#item-1)
|
||||
* [SWC](https://swcregistry.io/docs/SWC-107)
|
||||
* [Not so smart contract](https://github.com/crytic/not-so-smart-contracts/tree/master/reentrancy)
|
Loading…
Add table
Add a link
Reference in a new issue