Blockchain-Based-Cyber-Security-Pierre-Roberge

cmeasurecon

Blockchain-Based-Cyber-Security-Pierre-Roberge

Maximum number of bytes pushable to the stack

static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520;

// Maximum number of non-push operations per script

static const int MAX_OPS_PER_SCRIPT = 201;

// Maximum number of public keys per multisig

static const int MAX_PUBKEYS_PER_MULTISIG = 20;

// Maximum script length in bytes

static const int MAX_SCRIPT_SIZE = 10000;


function splitDAO(

uint _proposalID,

address _newCurator

) noEther onlyTokenholders returns (bool _success) {

...

// XXXXX Move ether and assign new Tokens. Notice how this is done first!

uint fundsToBeMoved =

(balances[msg.sender] * p.splitData[0].splitBalance) /

p.splitData[0].totalSupply;

if (p.splitData[0].newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender) ==

false) // XXXXX This is the line the attacker wants to run more than once

throw;

}

...

// Burn DAO Tokens

Transfer(msg.sender, 0, balances[msg.sender]);

withdrawRewardFor(msg.sender); // be nice, and get his rewards

// XXXXX Notice the preceding line is critically before the next few

totalSupply -= balances[msg.sender]; // XXXXX AND THIS IS DONE LAST

balances[msg.sender] = 0; // XXXXX AND THIS IS DONE LAST TOO

paidOut[msg.sender] = 0;

return true;


function withdrawRewardFor(address _account) noEther internal returns (bool _success)

{

if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply <

paidOut[_account])

throw;

uint reward =

(balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply -

paidOut[_account];

if (!rewardAccount.payOut(_account, reward)) // XXXXX vulnerable

throw;

paidOut[_account] += reward;

return true;

}

function payOut(address _recipient, uint _amount) returns (bool) {

if (msg.sender != owner || msg.value > 0 || (payOwnerOnly && _recipient != owner))

throw;

if (_recipient.call.value(_amount)()) { // XXXXX vulnerable

PayOut(_recipient, _amount);

return true;

} else {

return false;

}


The minimum debate period that a split proposal can have

uint constant minSplitDebatePeriod = 1 weeks;


function withdrawRewardFor(address _account) noEther internal returns (bool _success)

{

if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply <

paidOut[_account]) // XXXXX

throw;

uint reward =

(balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply -

paidOut[_account];

if (!rewardAccount.payOut(_account, reward)) // XXXXX

throw;

paidOut[_account] += reward;

return true;

}


function withdrawRewardFor(address _account) noEther internal returns (bool _success)

{

if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply <

paidOut[_account]) // XXXXX

throw;

uint reward =

(balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply -

paidOut[_account];

if (!rewardAccount.payOut(_account, reward)) // XXXXX

throw;

paidOut[_account] += reward;

return true;

}


function withdrawRewardFor(address _account) noEther internal returns (bool _success)

{

if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply <

paidOut[_account]) // XXXXX

throw;

...

return balances[_owner];

// The sum of ether (in wei) which has been sent to this contract

uint public accumulatedInput;


accumulatedInput

function() {

accumulatedInput += msg.value;

}

Similar magazines