Skip to content

Commit

Permalink
Add another contract with call to demonstrate re-entrancy vulnerability.
Browse files Browse the repository at this point in the history
Add another contract with call to demonstrate re-entrancy vulnerability as send explicitly sets gas to 2300 by default according to this commit 9ca7472 which makes it impossible to "get multiple refunds" because a non-zero CALL costs at least 9700 gas. This issue is discussed on Ethereum StackExchange https://ethereum.stackexchange.com/questions/30371/send-ether-reentrancy-attack-in-reality-how-could-fallback-function-make-a-mes/30616#30616
  • Loading branch information
medvedev-evgeny authored and axic committed Dec 12, 2017
1 parent 539b8f3 commit 2f6f816
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion docs/security-considerations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,24 @@ The problem is not too serious here because of the limited gas as part
of ``send``, but it still exposes a weakness: Ether transfer always
includes code execution, so the recipient could be a contract that calls
back into ``withdraw``. This would let it get multiple refunds and
basically retrieve all the Ether in the contract.
basically retrieve all the Ether in the contract. In particular, the
following contract will allow an attacker to refund multiple times
as it uses ``call`` which forwards all remaining gas by default:

::

pragma solidity ^0.4.0;

// THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract Fund {
/// Mapping of ether shares of the contract.
mapping(address => uint) shares;
/// Withdraw your share.
function withdraw() {
if (msg.sender.call.value(shares[msg.sender])())
shares[msg.sender] = 0;
}
}

To avoid re-entrancy, you can use the Checks-Effects-Interactions pattern as
outlined further below:
Expand Down

0 comments on commit 2f6f816

Please sign in to comment.