Merge pull request #3197 from medvedev1088/fix-security-considerations-example

Add another example with call to demonstrate Re-Entrancy
This commit is contained in:
Alex Beregszaszi 2017-12-12 04:22:45 +00:00 committed by GitHub
commit 40e8716926
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -69,10 +69,27 @@ complete contract):
}
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
of ``send``, but it still exposes a weakness: Ether transfer can always
include 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: