0

Suppose we want to handle ERC-20 tokens, but some of the token contracts does not comply with the standard completely. In IERC20 interface, transfer has the following signature.

function transfer(address to, uint value) external returns (bool);

In a solidity code, we can call the method of a contract like this:

bool success = IERC20(tokenAddress).transfer(to, value)

My questions are,

  1. What happens if the transfer method of the contract does not return anything.

    • Calling transfer ends up in revert?
    • Or assigning empty value to a boolean variable results in revert?
    • Or it doesn't revert and some value is assigned?
  2. What happens if the transfer method of the contract returns a value of another data type like uint

    • assigning a uint value to a boolean variable results in revert?
    • Or it doesn't revert and some value is assigned?

2 Answers 2

1

Hey again haha :) This is pretty easy to test, but yes, the call would revert in both cases (when the execution jumps back to your contract and the return data is checked)

1

I did some experiments and found the followings.

When a transfer method of a token contract is called, it returns a bytes. We can see the data using the following code.

(bool success, bytes memory data) = token.call(abi.encodeWithSignature('transfer(address,uint256)', to, value));
  • the length of the data is multiple of 32 bytes
  • small bit length data (e.g. uint160 or bool) is 0-padded towards 32 bytes
  • for example uint[3] has 96 bytes length
  • if the transfer function does not return anything, the byte length is 0

When we call the contract method like IERC20(tokenAddress).transfer(to, value), the return value is parsed based on the IERC20 interface. Suppose, the return type of the transfer function in IERC20 interface is bool. Then the data from the function call is decoded like this.

abi.decode(data, (bool))

This decoding works if the data is 32 bytes long and the value is 0 or 1.

Regarding my question Q1, it reverts because the length of the obtained data is 0, which cannot be decoded as bool.

For question Q2, it reverts unless the returned value is 0 or 1. (For example, suppose there is a ERC20 contract which implements the transfer function to return 0 or 1 of uint type. Then the data can be decoded as bool. Therefore the call does not revert)

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.