Skip to content

My solutions to Ethernaut's challenges. Make sure to check REAMDME file to learn more

Notifications You must be signed in to change notification settings

Aboudoc/Ethernaut-OpenZeppelin

Repository files navigation

Contributors Forks Stargazers Issues MIT License LinkedIn


Logo

The Ethernaut

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.

Prerequisites

  • npm

    npm install npm@latest -g
  • hardhat

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

    OpenZeppelin contract:

    npm install @openzeppelin/contracts

    run:

    npx hardhat

Installation

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

(back to top)

Usage

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

This project shows my responses of ETHERENAUT challenges. Each challenge comes with a contract that presents a vulnerability.

Fist of all get a new instance from Ethereaut

Use the instance address logged to the console to deploy the exploit. Address of the victim is set in the constructor.

Add your RPC url and private key to .env file

PRIVATE_KEY=
GOERLI_RPC_URL=

Note: Each challenge can be done/verified on Remix

07.Force

Challenge

Solution

In solidity, for a contract to be able to receive ether, the fallback function must be marked payable.

However, there is no way to stop an attacker from sending ether to a contract by self destroying. Hence, it is important not to count on the invariant address(this).balance == 0 for any contract logic.

08.Vault

Challenge

Solution

Copy instance address from the console and paste it as vaultAddress in exploitVault.js script

Run the exploit:

npx hardhat run scripts/exploitVault --network goerli

Another way getting the password using web3:

await web3.eth.getStorageAt(contract.address, 1)

It's important to remember that marking a variable as private only prevents other contracts from accessing it. State variables marked as private and local variables are still publicly accessible.

To ensure that data is private, it needs to be encrypted before being put onto the blockchain. In this scenario, the decryption key should never be sent on-chain, as it will then be visible to anyone who looks for it. zk-SNARKs provide a way to determine whether someone possesses a secret parameter, without ever having to reveal the parameter.

09.King

Challenge

The King's contract represents a very simple game: whoever sends it an amount of ether that is larger than the current prize becomes the new king. On such an event, the overthrown king gets paid the new prize, making a bit of ether in the process! As ponzi as it gets xD

Such a fun game. Your goal is to break it.

When you submit the instance back to the level, the level is going to reclaim kingship. You will beat the level if you can avoid such a self proclamation.

Solution

First, let's check the contract balance. Run it to the console:

await getBalance(contract.address)

The goal is to send more ETH than the actual balance from a malicious contract that doesn't got any receive function. This will revert the transaction sent from King contract and break the game.

Not having a fallback or a receive function is the same as:

fallback() external payable {
    revert();
}

Most of Ethernaut's levels try to expose (in an oversimplified form of course) something that actually happened — a real hack or a real bug.

In this case, see: King of the Ether and King of the Ether Postmortem.

10. Re-entrancy

Challenge

The goal of this level is for you to steal all the funds from the contract.

Things that might help:

Untrusted contracts can execute code where you least expect it. Fallback methods Throw/revert bubbling Sometimes the best way to attack a contract is with another contract. See the Help page above, section "Beyond the console"

Solution

In order to prevent re-entrancy attacks when moving funds out of your contract, use the Checks-Effects-Interactions pattern being aware that call will only return false without interrupting the execution flow. Solutions such as ReentrancyGuard or PullPayment can also be used.

transfer and send are no longer recommended solutions as they can potentially break contracts after the Istanbul hard fork Source 1 Source 2.

Always assume that the receiver of the funds you are sending can be another contract, not just a regular address. Hence, it can execute code in its payable fallback method and re-enter your contract, possibly messing up your state/logic.

Re-entrancy is a common attack. You should always be prepared for it!

The DAO Hack The famous DAO hack used reentrancy to extract a huge amount of ether from the victim contract. See 15 lines of code that could have prevented TheDAO Hack.

11. Elevator

Challenge

Solution

You can use the view function modifier on an interface in order to prevent state modifications. The pure modifier also prevents functions from modifying the state. Make sure you read Solidity's documentation and learn its caveats.

An alternative way to solve this level is to build a view function which returns different results depends on input data but don't modify state, e.g. gasleft().

(back to top)

Roadmap

  • Firsts challenges
  • Force
  • [-] King
  • Finish all challenges

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_AboutikaR - reda.aboutika@gmail.com

Project Link: https://github.com/Aboudoc/Ethernaut-OpenZeppelin

(back to top)

Acknowledgments

(back to top)

About

My solutions to Ethernaut's challenges. Make sure to check REAMDME file to learn more

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published