Ethernaut Puzzle 06 Delegation
It’s been half a year past since the last challenge. Let me start again and complete this series of challenges.
The sixth level of Ethernaut is a very interesting challenge that mainly tests our understanding of delegateCall.
delegatecall
is a low-level function in Solidity that is used to execute code from another contract in the context of the current contract. It is similar to call
, but with an important difference: when you use delegatecall
, the called contract’s code is executed with the current contract’s context, which means that any storage, balances, or other state variables will be those of the current contract.
Here’s an example of how delegatecall
works:
1 | pragma solidity ^0.8.0; |
In this example, A
has a reference to a B
instance and a setXFromB
function that uses delegatecall
to call B
‘s setX
function with the same argument. When setXFromB
is called, B
‘s code is executed in the context of A
, which means that the x
variable in A
will be set instead of the x
variable in B
.
It’s important to note that delegatecall
is a powerful tool, but also a dangerous one. If you’re not careful, you can inadvertently change the state of your contract in unexpected ways. Always make sure you understand how it works before using it, and test your code thoroughly to ensure that it behaves as expected.
This challenge requires us to claim the ownership of the Delegation
smart contract.
To claim the ownership, the method is straightforward, which is to find a way to call the fallback
function of Delegation
, and pass pwn()
as msg.data
. This will call the pwn()
function inside the Delegate smart contract and assign the ownership.
At first, my idea was to write a smart contract to claim the ownership. My smart contract looked like this:
1 | // SPDX-License-Identifier: MIT |
However, I realized later that this method would result in the ownership being assigned to the address of my smart contract instead of my address.
So, I needed to initiate the transaction myself and call the fallback
function of the Delegation
contract, passing pwn()
as msg.data.
Run these two commands in the console of the browser:
1 | var pwn_hacked = web3.utils.keccak256("pwn()") |
That’s done! Sumbit the instance!