mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #3197 from medvedev1088/fix-security-considerations-example
Add another example with call to demonstrate Re-Entrancy
This commit is contained in:
commit
40e8716926
@ -69,10 +69,27 @@ complete contract):
|
|||||||
}
|
}
|
||||||
|
|
||||||
The problem is not too serious here because of the limited gas as part
|
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
|
of ``send``, but it still exposes a weakness: Ether transfer can always
|
||||||
includes code execution, so the recipient could be a contract that calls
|
include code execution, so the recipient could be a contract that calls
|
||||||
back into ``withdraw``. This would let it get multiple refunds and
|
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
|
To avoid re-entrancy, you can use the Checks-Effects-Interactions pattern as
|
||||||
outlined further below:
|
outlined further below:
|
||||||
|
Loading…
Reference in New Issue
Block a user