EthereumCasts
EthereumCasts copied to clipboard
Reentry attack vulnerability in Campaign.sol
function finalizeRequest(uint index) public restricted {
Request storage request = requests[index];
require(request.approvalCount > (approversCount / 2));
require(!request.complete);
request.recipient.transfer(request.value);
request.complete = true;
}
When we are sending money to the recipient, nothing prevents a second recursive call to finalizeRequest. Even though the function is restricted, the recipient could pass control to the manager, who would then execute a recursive call. In this way, the manager, in cooperation with a vendor, could get an approval for a small amount, but withdraw many times that amount.
Technically, it would a solution to check that manager is a human and not a smart contract, but no such check is being done. Furthermore, one could make an innocent-looking smart contract, pretending it's just a convenience tool for the manager, in case someone decides to look, but keep it upgradable to leave a backdoor.
Update: the proposed solution is to interchange the last two lines, setting the flag to true before doing the transfer.
Just wondering what exactly was the fix?
Git diff I guess
You could swap the last two lines, setting complete to true before doing the transfer.