I was reading SafeERC20.sol (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) and Address.sol (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol), an there was the following snippet:

function verify(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
    if (success) {
        return returndata;
    } else {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly

            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
        } else {

In the example of contract {SafeERC20}, This verification follows transferFrom() of an ERC20 token. Can someone explain more about this function? Is it only for ERC20 tokens that return no value during transfers? What does it do here?

1 Answer 1


It is a compatibility layer for ERC20 tokens deployed before the standard was finalized.

In the final specification function should throw in case of an error.

For transfer it says

[..] The function SHOULD throw if the message caller’s account balance does not have enough tokens to spend.

The two problems the function try to fix are:

  • Tokens returning false instead of throwing.
  • Early draft token define transfer return nothing. This clash wit newer solc version that requires the function to return a bool.

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.