claimReward() after Ether is forcefully sent, so address(this).balance >= balance, user will receive more Ether than balance when calling claimReward(). this does not hurt the winner, so you as a smart contract coder can choose to reward the winner with balance or address(this).balance
Actually you can take all of the 7 ether, using a special function called create2. Here is how it works create2 is used to deploy a contract at the same address (even contracts that were previously deleted) 1. deploy Attack contract using create2 2. selfdestruct to force send Ether. this will delete Attack contract 3. use create2 to redeploy the Attack contract 4. Attack is the winner and can claim the 7 ethers
@@smartcontractprogrammer Another way would be to send 4 Ether when calling attack, which makes the Game ther to 6. Then quickly deposit the 1 Ether to the game like a normal player. to become the winner :)
Great! Very smart! I have question, In 3:35 line 49, you set the address of target as payable, does it means that we can change the address of another contract from non-payable to payable? It seems unreasonable?
What if the target was 7 ether, 3 ether were already sent, we make a selfdestruct in a contract that had another 3 ether and immediately deposit one more...3 easily stolen ether🤔
I was wondering if you could clarify something for me. Before the attack happens the EtherGame balance is 2 ether, the attack function is called forcefully sending 5 ether, making the balance = 7 ether. That would mean the attacker would be the winner no? The require(balance
Game requires each deposit to be exactly 1 ETH. Under normal circumstance, 7th depositor will win. However this rule can be broken by forcefully sending more than 1 ETH and immediately win the game
The attacker's 5 eth was sent forcefully via selfdestruct, not via the deposit function as intended; therefore, it did not go through the if condition that would set the winner. I believe if the game is not active enough, you could forcefully send 4 ether and then immediately send the remaining 1 ether to win the game on your demand. The caveat there would be that there is a probability some other player deposited just after your attack has finished. (someone else also suggested this in the comments) To be more reliable, you could write an attack with 2 contracts for that: say there is N ether remaining to win the game, and you have contract X with 1 ether and Y with N-1 ether. You write an attack function in X such that it calls an external function in your Y contract which will cause Y to selfdestruct and send its N-1 to the target, and right after that the next line in X attack will be to deposit 1 ether to the target, thereby winning the game. The game could also defend against this by only allowing EOA's to play, and disallow contracts (i.e. requiring that msg. sender == tx. origin)
@@ErhanTezcan Thank you for taking the time to reply. This makes much more sense now. For some reason I was thinking the eth that was forcefully sent was done through the deposit function instead of selfdestruct
I want to delete the contract itself. selfdestruct(0x0); But solidity says this does "Invalid implicit conversion" can you please tell me how to selfdestruct the contract ?
People cannot directly send Ether because the contract doesn't have a payable fallback function. That is why selfdestruct is used to forcefully send ETH and break the contract
Hi.. when i am trying to execute ethereum smart contracts by using Remix and the warning dispalys like and also code cannot be executed . plz solve this issue. Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: " to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see spdx.org for more information.
Reading through “Mastering Ethereum” and watching your videos for further clarification is gold 👌🏼 thank you
Overview of the exploit 0:42
Contract vulnerable to the exploit 1:54
Preventative technique 6:50
After creating the uint public balance variable - we would have to update the claimReward + getBalance functions too right?
claimReward()
after Ether is forcefully sent, so address(this).balance >= balance, user will receive more Ether than balance when calling claimReward().
this does not hurt the winner, so you as a smart contract coder can choose to reward the winner with balance or address(this).balance
Great video! One of the best channels for solidity if not the best!
is the best
😍 thanks for the video!! Very clear!! And breaking the game by wasting 5 Ether ?!!!! Truly self destructive!!! 😬
Actually you can take all of the 7 ether, using a special function called create2. Here is how it works
create2 is used to deploy a contract at the same address (even contracts that were previously deleted)
1. deploy Attack contract using create2
2. selfdestruct to force send Ether. this will delete Attack contract
3. use create2 to redeploy the Attack contract
4. Attack is the winner and can claim the 7 ethers
Smart Contract Programmer 😯 !!! Wow, that sounds like hacking!!! Will you cover create2 later ?
Breaking the game was possible with only 0.1 eth, in fact with every amount different from one because sum would never going to be == 7
@@smartcontractprogrammer how is the attack winner in step 4 ?
@@smartcontractprogrammer Another way would be to send 4 Ether when calling attack, which makes the Game ther to 6. Then quickly deposit the 1 Ether to the game like a normal player. to become the winner :)
Great! Very smart! I have question, In 3:35 line 49, you set the address of target as payable, does it means that we can change the address of another contract from non-payable to payable? It seems unreasonable?
yes
What happen if you sent 3 wei ? The contract will be blocked too because you verifiy that its strictly equal to 7 eth ?
What if the target was 7 ether, 3 ether were already sent, we make a selfdestruct in a contract that had another 3 ether and immediately deposit one more...3 easily stolen ether🤔
I was wondering if you could clarify something for me. Before the attack happens the EtherGame balance is 2 ether, the attack function is called forcefully sending 5 ether, making the balance = 7 ether. That would mean the attacker would be the winner no? The require(balance
Game requires each deposit to be exactly 1 ETH. Under normal circumstance, 7th depositor will win.
However this rule can be broken by forcefully sending more than 1 ETH and immediately win the game
The attacker's 5 eth was sent forcefully via selfdestruct, not via the deposit function as intended; therefore, it did not go through the if condition that would set the winner.
I believe if the game is not active enough, you could forcefully send 4 ether and then immediately send the remaining 1 ether to win the game on your demand. The caveat there would be that there is a probability some other player deposited just after your attack has finished. (someone else also suggested this in the comments)
To be more reliable, you could write an attack with 2 contracts for that: say there is N ether remaining to win the game, and you have contract X with 1 ether and Y with N-1 ether. You write an attack function in X such that it calls an external function in your Y contract which will cause Y to selfdestruct and send its N-1 to the target, and right after that the next line in X attack will be to deposit 1 ether to the target, thereby winning the game.
The game could also defend against this by only allowing EOA's to play, and disallow contracts (i.e. requiring that msg. sender == tx. origin)
@@ErhanTezcan Thank you for taking the time to reply. This makes much more sense now. For some reason I was thinking the eth that was forcefully sent was done through the deposit function instead of selfdestruct
I want to delete the contract itself.
selfdestruct(0x0);
But solidity says this does "Invalid implicit conversion"
can you please tell me how to selfdestruct the contract ?
selfdestruct(address(0))
@@smartcontractprogrammer hey thanx man appreciate it 👍
Awesome review,so amazing
hi, the question is not how to break the contract but how to retrieve all the ethers after Yves sent all 5 ethers
how do i test this using hardhat ?
great vid thanks. Please use dark theme. my eyes are hurting badly after competing the playlist
Is the self destruct function how people rug projects?
There are alot of ways to rug pull. Self destruct can be a part of it.
can attacker can update the balance variable
only increase by sending ETH
Nice video but a people has just to directly send 5 ether to the contract without calling a function and the contract will be broken
People cannot directly send Ether because the contract doesn't have a payable fallback function.
That is why selfdestruct is used to forcefully send ETH and break the contract
@@smartcontractprogrammer thks!
Is the ether stuck in the contract forever? How can someone get it out?
if there is a function to withdraw ETH, otherwise it's stuck
kool video, thank you
You are the best!
Cool!!!
Hi..
when i am trying to execute ethereum smart contracts by using Remix and the warning dispalys like and also code cannot be executed . plz solve this issue.
Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: " to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see spdx.org for more information.
Warning can be fixed if you put this up at the first line
// SPDX-License-Identifier: MIT
What error are you getting?