1

How can an address withdraw a contract's ether?

contract MyContract {
  address payable public withdrawAddress = 0x........; 

  constructor() public {
    owner = msg.sender;
  }

  function totalBalance() external view returns(uint) {
    return address(owner).balance;
  }

  function withdrawFunds() external withdrawAddressOnly() {
    msg.sender.transfer(this.totalBalance());
  }

  modifier withdrawAddressOnly() {
    require(msg.sender == withdrawAddress, 'only withdrawer can call this');
   _;
  }

  ...
}

I'm calling withdrawFunds() from the "withdrawAddress" address, but I'm getting the following error:

transact to MyContract.withdrawFunds errored: VM error: revert. revert The transaction has been reverted to the initial state. Note: The called function should be payable if you send value and the value you send should be less than your current balance. Debug the transaction to get more information.

I'm not setting the withdrawFunds as payable, because I'm not sending that function any funds to handle, the contract already has the funds. My intention is to transfer all the contracts' Ether to an address.

Here is a link to the code https://github.com/norris-labs/EthText/blob/main/EthText.sol

1 Answer 1

3

Please note that the function to retrieve the total balance doesn't seem to be correct: it is retrieving the owner's balance, but not the contract's balance.

I changed the constructor as payable and created the smart contract by including 1 ether during the creation, defining the owner variable (missing) and updating the totalBalance() function:

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

contract Test {

   address payable public withdrawAddress = 0xb5....;
   address public owner;

   constructor() public payable {
     owner = msg.sender;
   }

   function totalBalance() external view returns(uint) {
     //return address(owner).balance;
     return payable(address(this)).balance;
   }

   function withdrawFunds() external withdrawAddressOnly() {
     msg.sender.transfer(this.totalBalance());
   }

   modifier withdrawAddressOnly() {
     require(msg.sender == withdrawAddress, 'only withdrawer can call this');
   _;
   }
}

It is now working as expected and transferring the contract's balance to the designated withdrawAddress.

By the way, instead of declaring the constructor as payable (just for quick testing), I assume you might be using a specific function to receive ethers within the contract.

0

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.