According to the ERC-20 Token Standard, functions transfer
and transferFrom
should return a boolean value indicating success or failure:
interface IERC20Token {
function transfer(address _to, uint256 _value) public returns (bool);
function transferFrom(address _from, address _to, uint256 _value) public returns (bool);
}
Nevertheless, there are quite a few ERC-20 Token contracts which were deployed on mainnet without conforming to this requirement, i.e., without returning anything.
Suppose I use this interface in order to call these functions on the address of such contract:
IERC20Token token = IERC20Token(someAddress);
token.transfer(someAccount, someAmount);
And of course, because I'm not sure whether or not it returns a bool
, I simply ignore the return-value in my code.
The compiler, however, possibly allocates a slot on the stack for this return-value.
Could this possibly yield any sort of unexpected behavior?
Of course, I can force my code to assume that this function does not return anything, by declaring this interface:
interface INonStandardERC20Token {
function transfer(address _to, uint256 _value) public;
function transferFrom(address _from, address _to, uint256 _value) public;
}
And then using it:
INonStandardERC20Token token = INonStandardERC20Token(someAddress);
token.transfer(someAccount, someAmount);
But the thing is, I have no knowledge as to which one of these interfaces is implemented by the ERC-20 Token deployed at someAddress
.
So I'm even more worried about unexpected behavior in my second example, since in this case the compiler surely doesn't allocate any slot for the return-value, yet the function can possibly return something.
Any idea which approach of the two given above is safe?
Could the returndatasize
instruction possibly be useful here?
Thank you very much!