Ethernaut Solutions

Here are my solutions to the Ethernaut Challenges. Please note challenge #1 through #11 were solved using Remix so the solutions are in the form of Solidity contracts. Challenge #12 and beyond were done using Hardhat and so their solutions appear as Ethers.js test cases. Happy bug hunting! https://aaruni.io/2022/08/ethernaut-solutions-1-fallback https://aaruni.io/2022/08/ethernaut-solutions-2-fallout https://aaruni.io/2022/08/ethernaut-solutions-3-coinflip https://aaruni.io/2022/08/ethernaut-solutions-4-telephone https://aaruni.io/2022/08/ethernaut-solutions-5-token https://aaruni.io/2022/08/ethernaut-solutions-6-delegation https://aaruni.io/2022/08/ethernaut-solutions-7-force … Read more

Ethernaut Solutions: 27-Good Samaritan

Here we have a “Good Samaritan” contract that holds 10^6 “Coins” in a “Wallet”. Any account can call Good Samaritan’s requestDonation() function to receive 10 coins. The challenge is to somehow siphon off of 1 million coins in a single attempt using Wallet’s transferRemainder() function. As I was reading through the code, the first thing … Read more

Ethernaut Solutions: 26-DoubleEntryPoint

So this is a Forta demo in the guise of a security challenge. We are presented with two ERC20 tokens: LegacyToken and DoubleEntryPoint. Apparently LegacyToken is an old token that is forwarding all transfer() requests to DoubleEntryPoint. There is another contract CryptoVault that holds DET (DoubleEntryPoint) tokens. The challenge has 2 objectives: CryptoVault has a … Read more

Ethernaut Solutions: 25-Motorbike

To setup this challenge on Hardhat, I had to download v3.4.2 of Openzeppelin’s Address.sol and Initializable.sol. Find the 3.4.2 version here: https://www.npmjs.com/package/@openzeppelin/contracts?activeTab=versionsThen run the npm install command: Here, “openzeppelin-contracts-3.4.2” is the folder name that will be created in Hardhat and “contracts@3.4.2” defines the version to be installed. Also the Solidity compiler I used was 0.6.9 … Read more

Ethernaut Solutions: 24-Puzzle Wallet

This challenge requires a good understanding of how state variables behave when using delegatecall() in proxy pattern for upgradable contracts. I have expounded on these topics in my post: https://aaruni.io/deep-dive-upgradeable-smart-contracts I approached this challenge a bit differently. Instead of copying the contract into Hardhat and deploying from there, I deployed it from the browser using … Read more

Deep Dive: Upgradeable Smart Contracts

This post is a deep dive into the upgrade patterns for Smart Contracts targeted for Ethereum Virtual Machines (EVM). To understand this post you would need at least a beginner level understanding of Solidity, Hardhat and Ethers.js library. The topics we will explore are: Upgradable Smart Contracts: The Why? Smart contracts are immutable i.e., their … Read more

Ethernaut Solutions: 23-DexTwo

This is a classical case of an External Contract Referencing attack. The swap() method from the previous level “DEX” has been modified to remove the following check: As a result, we can supply swap() a maliciously written token contract. This malicious ERC20 contract would have to simply respond to balanceOf() and transferFrom() calls to make … Read more

Ethernaut Solutions: 22-Dex

The challenge is to find a way to upset the ratio inside getSwapPrice(). The way I did this is by using the Unexpected Ether attack except we will be transferring ERC20 tokens instead of ETH. Lookout for the below line in solution.js where I transfer tokens to DEX to upset the price calculation in my … Read more

Ethernaut Solutions: 21-Shop

The task is to ensure that the first call to _buyer.price() returns >= 100 and the next call to _buyer.price() returns < 100. To do that we monitor for a change in the value of boolean variable isSold in the Shop contract. We use an abstract class to execute Shop.buy() and to get the value … Read more

Ethernaut Solutions: 20-Denial

This is a good example of a DOS attack on a contract. Our task is to make the withdraw() fail when the owner calls it to withdraw ETH. The contract deployed at the “partner” address can easily do by spending all gas sent in the transaction through assert():