Share Dialog
Share Dialog
<100 subscribers
<100 subscribers
ERC20 standards are by far the most famous and used token standards in Ethereum. It provides set of functionality for the contracts to implement and those contract that implements considered to be ERC20 compliant tokens. In this blog, my goal is to introduce you interface of Openzeppelin, namely safeERC20 and its purpose.
When interacting with other ERC20 token contracts, as a programmer, you have to consider every cases to make your interaction SAFE. The reason behind this is the fact that not all ERC20 token implementations are ERC20 compliant or preference of implementation differs from tokenA to tokenB. First lets see the ERC20 interface and what makes a contract ERC20 compliant.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/IERC20.sol
interface IERC20 {
function totalSupply() external view returns (uint);
function balanceOf(address account) external view returns (uint);
function transfer(address recipient, uint amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
As you can see from the code above, the erc20 contract is required to provide return value on transfer and transferFrom function on transaction execution. On a successful transaction, the ERC20 compliant contracts must return True. On the other hand, the contract should return False in the case of a failed transaction; however, there are contracts that differ when it comes to implementation. For example, the DAI contract return returns False using revert in the case of failed transfer, while 0x contract simply returns False.
And we have some contracts that do not return True in a successful transaction; these are not ERC20 compliant but still might exist and we want to interact with those as well. The safeERC20 interface of openzeppelin provides methods that cover all the cases and helps your contract to interact with all options safely. Let see:

Let's first see how the function above handles the cases.
If a transfer function returns False, it will revert regardless during require check, so let's see what happens if the transaction execution is successful. In the case of ERC20 compliant contract, the return will be True, and it will evaluate the right-hand side of the logical and check. The first check will be False since there is a return (either False or True). The abi.decode method will decode the encoded data variable from the smart contract call and check. If it is True, the require check will pass. If False, well, it will fail.
The non-ERC20 compliant contracts that do not return True in a successful transaction. However, if the return is empty, the success will be True, meaning that there was an implementation of transfer in the token contract and that execution was True.
Now, it will evaluate the right-hand side of the logical and check. Here we can have two possibilities:
data.length == 0, meaning the return value is empty.
data.length ≠ 0, meaning that there is a bool return, either True or False. If either one of the checks is True, the require check will succeed.
Now you know why safeERC20 is preferred over traditional ERC20 interface.
ERC20 standards are by far the most famous and used token standards in Ethereum. It provides set of functionality for the contracts to implement and those contract that implements considered to be ERC20 compliant tokens. In this blog, my goal is to introduce you interface of Openzeppelin, namely safeERC20 and its purpose.
When interacting with other ERC20 token contracts, as a programmer, you have to consider every cases to make your interaction SAFE. The reason behind this is the fact that not all ERC20 token implementations are ERC20 compliant or preference of implementation differs from tokenA to tokenB. First lets see the ERC20 interface and what makes a contract ERC20 compliant.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.0.0/contracts/token/ERC20/IERC20.sol
interface IERC20 {
function totalSupply() external view returns (uint);
function balanceOf(address account) external view returns (uint);
function transfer(address recipient, uint amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
As you can see from the code above, the erc20 contract is required to provide return value on transfer and transferFrom function on transaction execution. On a successful transaction, the ERC20 compliant contracts must return True. On the other hand, the contract should return False in the case of a failed transaction; however, there are contracts that differ when it comes to implementation. For example, the DAI contract return returns False using revert in the case of failed transfer, while 0x contract simply returns False.
And we have some contracts that do not return True in a successful transaction; these are not ERC20 compliant but still might exist and we want to interact with those as well. The safeERC20 interface of openzeppelin provides methods that cover all the cases and helps your contract to interact with all options safely. Let see:

Let's first see how the function above handles the cases.
If a transfer function returns False, it will revert regardless during require check, so let's see what happens if the transaction execution is successful. In the case of ERC20 compliant contract, the return will be True, and it will evaluate the right-hand side of the logical and check. The first check will be False since there is a return (either False or True). The abi.decode method will decode the encoded data variable from the smart contract call and check. If it is True, the require check will pass. If False, well, it will fail.
The non-ERC20 compliant contracts that do not return True in a successful transaction. However, if the return is empty, the success will be True, meaning that there was an implementation of transfer in the token contract and that execution was True.
Now, it will evaluate the right-hand side of the logical and check. Here we can have two possibilities:
data.length == 0, meaning the return value is empty.
data.length ≠ 0, meaning that there is a bool return, either True or False. If either one of the checks is True, the require check will succeed.
Now you know why safeERC20 is preferred over traditional ERC20 interface.
No comments yet