4

Hello is it possible to execute this "multiplicate" function? Assume I put 1 ETH to the contract as an owner, but when a hacker sends 2 ETH to the multiplicate, this.balance becomes 3 at the beginning of the function and then it's always greater than the msg.value. I wonder if I am missing something.

contract Multiplicator
{
    address public Owner = msg.sender;

    function() payable{}

    function withdraw() payable public
    {
        require(msg.sender == Owner);
        Owner.transfer(this.balance);
    }

    function multiplicate(address adr) payable
    {
        if(msg.value >= this.balance)
        {        
            adr.transfer(this.balance+msg.value);
        }
    }
}

3 Answers 3

8

Question 1: When is this.balance updated?

The value of this.balance in payable methods is increased by msg.value before the body of your payable method executes. If your contract has a starting balance of 1 and you pass in a msg.value of 2, the payable method will already have a this.balance of 3 when it executes.

Question 2: Is it possible to [successfully] execute this multiplicate function?

Yes. If the contract's initial balance is zero and you pass in a msg.value of zero, the function will most likely complete without error. I wrote "most likely", since if the receiving address is a contract, the receiving contract could still make it fail.

Your example, where the contract starts with 1 ether and you invoke multiplicate with a msg.value of 2 ether, will also execute successfully, but the inner condition invoking transfer will be skipped over. this.balance will jump to 3 before the body of multiplicate executes.

1

What you should do is add a state variable that keeps track of the contract's balance. That way you could do:

function multiplicate(address adr) payable
{
  require (contractBalance + msg.value <= this.balance); // The contract should have enough funds...
  if(msg.value >= contractBalance)
  { 
    contractBalance += msg.value;
    uint moneyToTransfer = contractBalance;
    contractBalance = 0;
    adr.transfer(moneyToTransfer);
  }
}

You would have to keep track of contractBalance each time you receive or transfer eth.

1

Yes, I think this update came along with solidity 0.6.0

this.balance

should be replaced with

address(this).balance

Hope this helps

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.