Code Monkey home page Code Monkey logo

reentrancy-attack's Introduction

Contributors Forks Stargazers Issues MIT License LinkedIn


Logo

Reentrancy Attack

project_description
Explore the docs »

View Demo · Report Bug · Request Feature

Table of Contents
  1. About The Project
  2. Getting Started
  3. Usage
  4. Roadmap
  5. Contributing
  6. License
  7. Contact
  8. Acknowledgments

About The Project

Product Name Screen Shot

(back to top)

Built With

  • Hardhat
  • Ethers

(back to top)

Getting Started

To get a local copy up and running follow these simple example steps.

Getting Started

To get a local copy up and running follow these simple example steps.

Prerequisites

  • npm

    npm install npm@latest -g
  • hardhat

    npm install --save-dev hardhat
    npm install @nomiclabs/hardhat-ethers @nomiclabs/hardhat-waffle

    run:

    npx hardhat

Installation

  1. Clone the repo
    git clone https://github.com/Aboudoc/Reentrancy-demo.git
  2. Install NPM packages
    npm install

(back to top)

Usage

If you need testnet funds, use the Alchemy testnet faucet.

This project shows the re-entrancy attack and how to protect against it

Checks-Effects-Interactions Pattern

The simplest way to eliminate reentrancy bugs is to use the checks-effects-interactions pattern.

    function withdraw() external {
        require(balances[msg.sender] > 0);
        (bool success, ) = msg.sender.call{value: balances[msg.sender]}("");
        require(success);
        balances[msg.sender] = 0;
    }

If msg.sender is a smart contract, it has an opportunity to call withdraw() again before the next line happens. In that second call, balanceOf[msg.sender] is still the original amount, so it will be transferred again. This can be repeated as many times as necessary to drain the smart contract.

    function withdraw() external {
        require(balances[msg.sender] > 0);
        balances[msg.sender] = 0;
        (bool success, ) = msg.sender.call{value: balances[msg.sender]}("");
        require(success);
    }

The idea of the checks-effects-interactions pattern is to make sure that all your interactions (external calls) happen at the end

Use a Reentrancy Guard

Another approach to preventing reentrancy is to explicitly check for and reject such calls. Here’s a simple version of a reentrancy guard so you can see the idea:

    bool locked = false;

    function withdraw() external {
        require(!locked, "Reentrant call detected")

        locked = true;
        require(balances[msg.sender] > 0);
        (bool success, ) = msg.sender.call{value: balances[msg.sender]}("");
        require(success);
        balances[msg.sender] = 0;

        lock = false;
    }

With this code, if a reentrant call is attempted, the require will reject it because lock is still set to true

A more sophisticated and gas-efficient version of this can be found in OpenZeppelin’s ReentrancyGuard contract. If you inherit from ReentrancyGuard, you just need to decorate functions with nonReentrant to prevent reentrancy.

Please note that this method only protects you if you explicitly apply it to all the right functions. It also carries an increased gas cost due to the need to persist a value in storage.

Stop Using Solidity's transfer()

EIP-1884 increases the gas cost of the SLOAD operation and therefore breaks some existing smart contracts because their fallback functions used to consume less than 2300 gas, and they’ll now consume more.

Why is 2300 gas significant? It’s the amount of gas a contract’s fallback function receives if it’s called via Solidity’s transfer() or send() methods.

Since its introduction, transfer() has typically been recommended by the security community because it helps guard against reentrancy attacks. This guidance made sense under the assumption that gas costs wouldn’t change, but that assumption turned out to be incorrect. We now recommend that transfer() and send() be avoided.

Any smart contract that uses transfer() or send() is taking a hard dependency on gas costs by forwarding a fixed amount of gas: 2300.

The whole reason transfer() and send() were introduced was to address the cause of the infamous hack on The DAO. The idea was that 2300 gas is enough to emit a log entry but insufficient to make a reentrant call that then modifies storage.

Remember, though, that gas costs are subject to change, which means this is a bad way to address reentrancy anyway. When Constantinople fork was delayed it was because lowering gas costs caused code that was previously safe from reentrancy to no longer be.

(back to top)

Roadmap

  • unit test

See the open issues for a full list of proposed features (and known issues).

(back to top)

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

(back to top)

License

Distributed under the MIT License. See LICENSE.txt for more information.

(back to top)

Contact

Reda Aboutika - @twitter - [email protected]

Project Link: https://github.com/Aboudoc/Reentrancy-demo

(back to top)

Acknowledgments

(back to top)

reentrancy-attack's People

Contributors

aboudoc avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.