mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add another contract with call to demonstrate re-entrancy vulnerability.
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
This commit is contained in:
parent
539b8f3b45
commit
2f6f81640b
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user