Skip to content

Commit

Permalink
🎉 Added README.md till challenge #10
Browse files Browse the repository at this point in the history
  • Loading branch information
abdulsamijay committed May 22, 2022
1 parent 6f20c4c commit 1f32514
Show file tree
Hide file tree
Showing 68 changed files with 191 additions and 84 deletions.
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ out = 'out'
libs = ['lib']

optimizer = false

FOUNDRY_IGNORED_ERROR_CODES=[9302,2072,5667,2018,3628,1878]

remappings = [
"@openzeppelin/=lib/openzeppelin-contracts/"
Expand Down
File renamed without changes.
18 changes: 5 additions & 13 deletions src/challenge-1/README.md → src/Challenge-1-Fallback/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Ethernaut Challenge 1 - using foundry
## Ethernaut Challenge 1

In this challenge the user is provided with a contract called [`Fallback`](./Fallback.sol). The goal of this challenge is to become the onwer of the contract & drain all the funds (Eth).

Expand All @@ -15,18 +15,10 @@ This challenge requires user to be familiar with the following concepts.
- So, First we call `contribute()` with `Eth > 0` (i.e 0.0009 Eth) this will increase our value from 0 to some positive number. Then we send `Eth > 0` (i.e 0.1 Eth) to the contract where our conditions fulfill & now we are the `owner` of the contract.
- Next, we call `withdraw()` & receive all the funds to ourself. (0x1337 in this case).

However, I have solved this challenge [`Challenge-1`](./src/Challenge1.sol) using a contract that can be found in [`test/Challenge1.sol`](./test/Challenge1.t.sol).
However, I have solved [`Fallback`](./src/Fallback.sol) using a contract that can be found in [`test/Challenge1.sol`](./test/Fallback.t.sol).

1. `Cd` into challenge-1/
1. Run Exploit!

```sh
cd challenge-1/
```
2. Run forge build
```sh
forge build
```
3. Exploit!
```sh
forge test -vv -m test_challenge_1
```
cd .. && forge test -vv -m test_challenge_1
```
File renamed without changes.
16 changes: 4 additions & 12 deletions src/challenge-0/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Ethernaut Challenge 0 - using foundry
## Ethernaut Challenge 0

In this challenge the user is provided with a contract instance upon calling the `Get Instance` button on the page. The challenge is to retrieve the `password` hidden in the contract & call `authenticate()` with a password. If the user enters correct passord the isCleared flag becomes true & level is assumed to be cleared.

Expand All @@ -11,19 +11,11 @@ The user needs to navigate through the contract instance by opening up chrome de

### I have solved it a bit differently!

However, I have solved this challenge [`Challenge-0`](./src/Challenge0.sol) using a contract that can be found in [`test/Challenge0.sol`](./test/Challenge0.t.sol).
However, I have solved the [`Challenge-0`](./Challenge0.sol) using a contract that can be found in [`test/Challenge0.sol`](./test/Challenge0.t.sol).

1. `Cd` into challenge-0/
1. Run Exploit!

```sh
cd challenge-0/
cd .. && forge test -vv -m test_challenge_0
```
2. Run forge build
```sh
forge build
```
3. Exploit!

```sh
forge test -vv -m test_Challenge_0
```
1 change: 1 addition & 0 deletions src/challenge-0/test/Challenge0.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ contract ContractTest is Test {
Challenge0 c0;

function test_Challenge_0() public {
console.log("Challenge #0");
c0 = new Challenge0("ethernaut0");

// Wrong pass.
Expand Down
File renamed without changes.
17 changes: 17 additions & 0 deletions src/challenge-10-Reentrance/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Ethernaut Challenge 10

In this challenge the user is provided with a contract called [`Reentrance.sol`](./Reentrance.sol). The goal of this challenge to drain the contract.

This challenge requires user to be familiar with the following concepts.
- Checks-effects-interaction pattern

### Solution
- Create a contract [`Atatck.sol`](./Atatck.sol) that has a function to call the fallback of [`Reentrance.sol`](./Reentrance.sol) using `drain()`.
- When the ether are received in `Attack` contract it invoke its fallback function where it gives us the control over the execution.
- We call the `withdraw()` in the fallback to re-enter the contract to drain it.

1. Run Exploit!

```sh
cd .. && forge test -vv -m test_challenge_10
```
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ contract AlienCodex is Ownable {
codex.length--;
}

function len() public returns (uint256) {
return codex.length;
}

function revise(uint256 i, bytes32 _content) public contacted {
codex[i] = _content;
}
Expand Down
File renamed without changes.
File renamed without changes.
20 changes: 4 additions & 16 deletions src/challenge-2/README.md → src/challenge-2-Fallout/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Ethernaut Challenge 2 - using foundry
## Ethernaut Challenge 2

In this challenge the user is provided with a contract called [`Fallout`](./Fallout.sol). The goal of this challenge is to become the onwer of the contract & drain all the funds (Eth).

Expand All @@ -15,22 +15,10 @@ This challenge requires user to be familiar with the following concepts.
- If we look closely, there is a function called `Fallout()` which accepts ether & allows anybody to become onwer by sending Eth to that function.
- The user becomes the new owner of the contract.

However, I have solved this challenge [`Challenge-2`](./src/Challenge2.sol) using a contract that can be found in [`test/Challenge2.sol`](./test/Challenge2.t.sol).
However, I have solved the [`Fallback`](./Fallback.sol) using a contract that can be found in [`test/Challenge2.sol`](./test/Fallout.t.sol).

1. `Cd` into challenge-2/
1. Run Exploit!

```sh
cd challenge-2/
```

2. Run forge build

```sh
forge build
```

3. Exploit!

```sh
forge test -vv -m test_challenge_2
cd .. && forge test -vv -m test_challenge_2
```
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ contract ContractTest is Test {
console.log("Token0 drained from dex!");
}

function logSwapPrice() public {
function logSwapPrice() public view {
console.log("-------------- SWAP -----------------");
console.log("1337 token0 balance", token0.balanceOf(address(1337)));
console.log("1337 token1 balance", token1.balanceOf(address(1337)));
Expand Down
File renamed without changes.
35 changes: 35 additions & 0 deletions src/challenge-23-DexTwo/FakeERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

contract FakeERC20 {
function approve(address addr, uint256 amount) public pure returns (bool) {
// Silence compiler
{
addr;
amount;
}
return true;
}

function balanceOf(address account) public pure returns (uint256) {
// Silence compiler
{
account;
}
return 1;
}

function transferFrom(
address spender,
address receiver,
uint256 amount
) public pure returns (bool) {
// Silence compiler
{
spender;
receiver;
amount;
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ contract ContractTest is Test {
console.log("Token1 drained from dex!");
}

function logSwapPrice() public {
function logSwapPrice() public view {
console.log("-------------- SWAP -----------------");
console.log("1337 token0 balance", token0.balanceOf(address(1337)));
console.log("1337 token1 balance", token1.balanceOf(address(1337)));
Expand Down
20 changes: 0 additions & 20 deletions src/challenge-23/FakeERC20.sol

This file was deleted.

File renamed without changes.
File renamed without changes.
18 changes: 3 additions & 15 deletions src/challenge-3/README.md → src/challenge-3-CoinFlip/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Ethernaut Challenge 3 - using foundry
## Ethernaut Challenge 3

In this challenge the user is provided with a contract called [`Coinflip.sol`](./CoinFlip.sol). The goal of this challenge is win 10 times consecutively by calling the `flip()` function of the contract.

Expand All @@ -15,20 +15,8 @@ This challenge requires user to be familiar with the following concepts..

However, I have solved this challenge [`Challenge-3`](./src/CoinFlip.sol) using a contract that can be found in [`test/CoinFlip.t.sol`](./test/CoinFlip.t.sol).

1. `Cd` into challenge-3/
1. Run Exploit!

```sh
cd challenge-3/
```

2. Run forge build

```sh
forge build
```

3. Exploit!

```sh
forge test -vv -m test_challenge_3
cd .. && forge test -vv -m test_challenge_3
```
File renamed without changes.
18 changes: 18 additions & 0 deletions src/challenge-4-Telephone/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
## Ethernaut Challenge 4

In this challenge the user is provided with a contract called [`Telephone.sol`](./Telephone.sol). The goal of this challenge claim the ownership of the contract.

This challenge requires user to be familiar with the following concepts..

- Difference between `tx.origin` & `msg.sender`

### Solution

- The [`Telephone contract`](./Telephone.sol) has a `changeOwner()` that takes in an address value.
- The function which can be called from a custom contract that will change the `tx.origin` value from the `msg.sender` allowing us to set whatever address we want the onwer to be.

1. Run Exploit!

```sh
cd .. && forge test -vv -m test_challenge_4
```
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ contract ContractTest is Test {
}

function test_challenge_4() public {
console.log("Challenge #4");
console.log("Onwner Of telephone before", t.owner());

vm.startPrank(address(1337));
Expand Down
15 changes: 15 additions & 0 deletions src/challenge-5-Token/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## Ethernaut Challenge 5

In this challenge the user is provided with a contract called [`Token.sol`](./Token.sol). The goal of this challenge is to hack the the token contract.

### Solution

- The [`Token contract`](./Token.sol) has a `transfer()` functions that takes in an address & value.
- It has a check that should be checking for interger overflow but the condition `require(balances[msg.sender] - _value >= 0);` will always returns `0`.
- Here we also need to make sure that `msg.sender` has some tokens otherwise `balances[msg.sender] -= _value;` will be overflowed.

1. Run Exploit!

```sh
cd .. && forge test -vv -m test_challenge_5
```
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ contract ContractTest is Test {
}

function test_challenge_5() public {
console.log("Challenge #5");

console.log("Initial balance of 0x1337", t.balanceOf(address(1337)));
vm.startPrank(address(te));
te.exploit(address(1337), 10000);
Expand Down
File renamed without changes.
19 changes: 19 additions & 0 deletions src/challenge-6-Delegation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## Ethernaut Challenge 6

In this challenge the user is provided with a contract called [`Delegate.sol`](./Delegate.sol). The goal of this challenge claim the ownership of the contract.

This challenge requires user to be familiar with the following concepts..
- Solidity `delegtecall` function & storage layout.
- Fallback functions.

### Solution

- We can simply invoke fallback of [Delegation](./Delegate.sol) which has the exact same storage variable layout as [Delegate](./Delegate.sol). It will make a `delegatecall` to [Delegate contract](./Delegate.sol) which will set the owner to out address i.e `msg.sender`.
- This storage layout is important because whenever a `delegatecall` is made to another contract `msg.sender` & `msg.value` are preserved but the storage changes will be made to the contract from which th `delegatecall` started.
- In other word, whenever a `delegatecall` is made from `A` to function in another contract `B` that function behaves as it was the the part of the contract `A`. If any state changes are made, they are made in contract `A` storage.

1. Run Exploit!

```sh
cd .. && forge test -vv -m test_challenge_6
```
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ contract ContractTest is Test {
deal(address(1337), 1 ether);
vm.startPrank(address(1337));
address(delegation).call{value: 0.1 ether}(
abi.encodeWithSignature("0xdd365b8b")
// bytes4(keccack256("pwn()"))
abi.encodeWithSignature("0xdd365b8b")
);
console.log("owner after", delegate.owner());
vm.stopPrank();
Expand Down
File renamed without changes.
16 changes: 16 additions & 0 deletions src/challenge-7-Force/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Ethernaut Challenge 7

In this challenge the user is provided with a contract called [`Force.sol`](./Force.sol). The goal of this challenge to send ether to the contract that has no ability to receive ether.

This challenge requires user to be familiar with the following concepts..
- Solidity `selfdestruct()` function

### Solution
- We create a contract [`ForceSend`](./Force.sol) & use selfdestruct to forcefully send the ether to the contract.
- Since the contract addresses can be predicted, it is possible to send ether to an address & later deploy a contract at it.

1. Run Exploit!

```sh
cd .. && forge test -vv -m test_challenge_7
```
File renamed without changes.
29 changes: 29 additions & 0 deletions src/challenge-8-Vault/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## Ethernaut Challenge 8

In this challenge the user is provided with a contract called [`Vault.sol`](./Vault.sol). The goal of this challenge to unlock the vault.

This challenge requires user to be familiar with the following concepts.

- Storage or slot packing technique while contract creation.

### Solution

- Private variables of a contract cannot be accessed from another smart contract unless it is inherting the contract. But contract storage slots can be accessed off-chain through an ethereum RPC endpoint using.

```js
const provider = new providers.JsonRpcProvider(
{ url: YOUR_ETHEREUM_RPC_URL },
1
);
let pass = await provider.getStorageAt("YOU_INSTANCE_ADDRESS", 1);
console.log("The password is :", pass);
```

### Alternative solution
- For demostrative pruposes, I have created a function call `getValueAtSlot()` in [`Vault.sol`](./Vault.sol) to get the storage at slot `1` as it is where the value of the `password` in bytes32 is stored.

1. Run Exploit!

```sh
cd .. && forge test -vv -m test_challenge_8
```
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
17 changes: 17 additions & 0 deletions src/challenge-9-King/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
## Ethernaut Challenge 9

In this challenge the user is provided with a contract called [`King.sol`](./King.sol). The goal of this challenge to become the king in such a way that no one should be able to overpay & become the king.

This challenge requires user to be familiar with the following concepts.
- Solidity `fallback()` funtion.

### Solution
- Create a contract [`AttackKing.sol`](./AttackKing.sol) that has a function to call the fallback of [`King.sol`](./King.sol).
- We also include a `fallback()` function in out contract for handling event when receiving Eth. And force the transaction to fail is anyone send ether to it by `require(false, "Can't overthrow me!");` to never be overthrown.
- We call the [`AttackKing.sol`](./AttackKing.sol) with amount of eth that is greater than `prize` which makes our contract the king.

1. Run Exploit!

```sh
cd .. && forge test -vv -m test_challenge_9
```
File renamed without changes.

0 comments on commit 1f32514

Please sign in to comment.