From the Solidity documentation I do not understand if the recently introduced address.transfer forwards all gas to the target contract or just gives a minimal gas stipend. I.e.: Would it facilitate re-entrancy attacks?


I setup a minimal test example that you can find on https://gist.github.com/anonymous/07d4714c27dbf1af0e5cb16c9f833353

pragma solidity ^0.4.11;

contract Test {
    Receiver myR;

    function setReceiver (address a) {
        myR = Receiver(a);

    function callR() {

    function sendCash() payable {


contract Receiver {
    uint public numCalled;

    function () payable {

Which works well and after setting the Receiver contract address in Test via setReceiver and upon calling callR the numCalled in Receiver increases. When replacing the myR.call by myR.transfer I get an exception. Single-stepping with the Remix debugger into this shows that myR.transfer only got a gas stipend of 2300 gas which is not sufficient to set a storage variable or recursive calls.

Hence I conclude that transfer is save and does not allow for re-entrancy attacks.


Try it and find out?

contract TestInterface {
  function reentrance(address dest);

contract Test is TestInterface {
  uint8 private _depth = 0;

  // make it payable
  function () payable {}

  event Entered(uint8 depth);

  function reentrance(address dest) {
    if (_depth > 2) {
      // yep

contract Destination {
  function () payable {
    TestInterface sender = TestInterface(msg.sender);
    // send it back so we can do it again.

// deploy Test
// send Test some ETH
// Deploy Destination
// call Test.reentrance with Destination's address
// Watch for events from Test

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.