18

The question in the title says it all.

To the best of my understanding, the only way to deposit ether into a contract is by calling a payable function, and set msg.value larger than 0 (and of course, the function should complete successfully without reverting).

But if there are no payable functions to begin with, is it ever possible that the ether balance of the contract will be larger than 0?

Thank you!

goodvibration
  • 26,003
  • 5
  • 46
  • 86

1 Answers1

24

Yes, a contract can have Ether balance without any payable function.

There are four ways how it's possible:

  1. selfdestruction. Another contract self destructs (by using the selfdestruct functionality) and sends its remaining Ether to your contract

  2. Target of mining (so called coinbase address). Ether rewarded from mining can't be refused. EDIT after switching to Proof of Stake: PoS validators can choose where their issued rewards are sent - this issuance can't be refused by contracts

  3. Ether sent to the contract before the contract exists.

  4. Ether sent to a contract before Solidity version 0.4, since payable was introduced only in that version

More details about these alternatives can found for example here: https://medium.com/@alexsherbuck/two-ways-to-force-ether-into-a-contract-1543c1311c56

Lauri Peltonen
  • 29,391
  • 3
  • 20
  • 57
  • Great, thank you! Question on bullet #3: So this is just "a long shot in the dark"? I send ether to some public address without knowing it's private key, and at a later point in time, somebody deploys a contract which happens to "fall" on the same address - is that correct, or have I misinterpreted you intention? – goodvibration Dec 12 '18 at 12:56
  • 3
    @goodvibration The chance of someone generating any completely random address (either through a private key or contract deployment) is incredibly small. However, contract addresses are not random, they are deterministic. For any given address, you can know in advance the contract addresses it will generate: https://ethereum.stackexchange.com/questions/9776/generate-contract-address-using-nonce – Jesbus Dec 12 '18 at 14:29
  • 5
    Additionally, a trivial case: before Solidity 0.4 payable didn't exist, so all those Solidity contracts have ether without a payable function :) – eth Dec 13 '18 at 02:52
  • 4
    @goodvibration you may be interested to know about Create2 and the ability to know a contract's address before it is deployed. https://forum.openzeppelin.com/t/guide-to-using-create2-sol-library-in-openzeppelin-contracts-2-5-to-deploy-a-vault-contract/2268 – Nick Feb 21 '20 at 12:11