Open montyly opened 5 years ago
If this can help to debug, here a "simplified" version of the DAO reentrancy, which is also not detected by Securify:
contract Wallet{
address owner = msg.sender;
function cashOut(address account, uint amount) external{
require(owner == msg.sender);
account.call.value(amount)();
}
function () payable{
}
}
contract DAO{
Wallet w;
mapping(address => uint) balances;
constructor(){
w = new Wallet();
}
function buy() payable{
balances[msg.sender] += msg.value;
w.transfer(msg.value);
}
function bug() external{
w.cashOut(msg.sender, balances[msg.sender]);
balances[msg.sender] = 0;
}
}
I have checked the following
[X] The
souffle
binary is available, output when runningsouffle
:[X] Output of
solc --version
[X] Output of
solc --bin-runtime MyContract.sol
Tested from the master branch aef12a3f0741498800dd992b422f3ee07ce4142d
Steps to reproduce
Hi,
The latest version of securify (aef12a3f0741498800dd992b422f3ee07ce4142d) fails to find the DAO reentrancy bug.
The run reports multiple potential reentrancies, but does not report the one responsible for the DAO hack.
As a recall (see http://hackingdistributed.com/2016/06/18/analysis-of-the-dao-exploit/), the bug lies in the function
withdrawRewardFor
, a malicious attacker controlling_account
can re-enter beforepaidOut
is updated during the call topayOut
:This was tested with Solidity 0.4.25, on this modified version of the DAO:
The modifications are:
The reentrancy results from Securify are:
But the reentrancy used during the hack is not detected. Please let me know if I am missing something, or if you need more information.
Thanks!