What makes a lowlevel `call` return false and what opcodes fail but do not revert?

Say I implement a transferETH function in contract A:

function transferETH(address _to, uint256 _value) public returns (bool) {
        (bool success, ) = _to.call{value: _value}("");
        return success;
}

and I implemented a fallback function in contract B like so:

fallback() payable external {
    assembly {
        stop()
    }
}

or

fallback() payable external {
    assembly {
        invalid()
    }
}

which of the two fallback functions would cause a call to them to return false but keep any ETH sent in the call?

Thanks!

Hi, welcome! :wave:

I am not sure for this, I remember the opcode stop will return (0,0), but for the opcode invalid, I am not sure.
@frangio @martriay Could you please have a look at this issue? Thanks!

It is not possible to return false and keep ETH sent in the call. Returning false means that the call was reverted, i.e. its state changes were reverted, and ETH balances are considered a state change. The only ETH that is “transferred” for reverted function calls is the gas paid to the miner.

4 Likes

Alright, thank you so much!