Here is an example of such transaction:
etherscan
It was 569730199030000 Wei on a balance,
I used current gas price(by web3.eth.getGasPrice()
) 19888345864 Wei.
So my estimated fee was (19888345864 * 21000) 417655263144000 Wei.
I was trying to send (balance - estimated fee) = 152074935886000 Wei.
The result as you can see "out of gas".
Why it is possible that regular send was required more than 21000 gas? If I understand properly in case if gas price is not enough then miners simply must ignore this tx, but in case if they are agree with the gas price they have to run this transaction normally, and normally sending eth requires gas limit 21000. Where is mistake in my calculations and how to execute such tx properly?
Generally, this often happens when you're trying to send ETH to a contract that either doesn't implement a special function to accept the ETH - or the contract does implement the function but it explicitly rejects the incoming transfer.
Specifically, the first-hand recipient of your transaction is a proxy contract deployed at address 0xB233903ACec807C61eeeCc4F69dd795A617a1732, that redirects the request to a target contract deployed at address 0xd332254f274cc65aa11178b74734e2992b8f349e.
Author of the target contract has not shared its source code, but from the decompiled bytecode it seems to accept incoming ETH transfer only if series of conditions (depending on the payload of the incoming transaction and the state of another contract) is met. Otherwise it rejects the transaction with the revert
statement.
def _fallback() payable: # default function
require ext_code.size(0xa24787320ede4cc19d800bf87b41ab9539c4da9d)
static call 0xa24787320ede4cc19d800bf87b41ab9539c4da9d.0x4fef8ec4 with:
gas gas_remaining wei
if not ext_call.success:
revert with ext_call.return_data[0 len return_data.size]
require return_data.size >= 32
delegate ext_call.return_data[0] with:
funct call.data[0 len 4]
gas gas_remaining wei
args call.data[4 len calldata.size - 4]
if not delegate.return_code:
revert with ext_call.return_data[0 len return_data.size]
return ext_call.return_data[0 len return_data.size]