0

I am newbie to the smart contract development & have developed a smart contract that can transfer ERC20 tokens to multiple addresses in single transaction. I test it by creating new Tokens & it works. However i have been using USDC Token for quite long time https://rinkeby.etherscan.io/address/0x83cb1597cf92f0a492be26311fd88d08cab53859 when i try to use that token to transfer USDC to some addresses the transaction fails with error execution reverted sample transaction : https://rinkeby.etherscan.io/tx/0xb072684709e11d3c18db61f2ca7e9e5432cef00b790fb2e38f3acd8258c9ed56

main functions in my contract are

     /**
     * @dev sends a internal transaction based on the currency specified in the
     * parameters, it use the ERC20 interface for currencies stored in the contracts
     * map
     */
    function withdrawalERC (IERC20 token, address _client, uint256 _amount) private {
        require(_client != address(0), "address needs to be given");
        require(_amount > 0, "amount needs to be greater than 0");

        require(token.balanceOf(address(this)) >= _amount, "not enough token funds to send transaction");
        token.transfer(_client, _amount);
    }
     /**
     * @dev sends multiple internal transactions based on the currency specified in the
     * parameters, check "withdrawalERC" for more details, this method just handles the parameters list
     */
    function batchWithdrawalERC(address token_addr, address[] calldata _clients, uint256[] calldata _amounts) external onlyOwner {
        require(_clients.length == _amounts.length, "address, amount array length need to be equal");
        require(token_addr != address(0), "invalid contract address");

        IERC20 iERC20 = IERC20(token_addr);
        for (uint16 i=0; i < _clients.length; i++) {
            withdrawalERC(iERC20, _clients[0], _amounts[0]);
        }
    }

My questions are

  • Is the logic good enough to perform batch transfer ?
  • How can i deploy ERC20 token e. g USDC that is more close to mainnet USDC token? or even if its is possible ?

Any guidance would be much appreciated

1 Answer 1

0

Looking at the transaction trace. The error happens after the call to transfer() in 0x83cb1597cf92f0a492be26311fd88d08cab53859 (USDC contract).

In the call the returned value is empty "0x"

{
  "type": "CALL",
  "from": "0xa1ac4bb3b1c9a3d73df00eeedcba7e16d2e58f23",
  "to": "0x83cb1597cf92f0a492be26311fd88d08cab53859",
  "value": "0x0",
  "gas": "0x2c91c2",
  "gasUsed": "0x2cf4",
  "input": "0xa9059cbb000000000000000000000000de76d3f38b342f988f0d73a2c6b7d1d527b3d5d000000000000000000000000000000000000000000000000000000000000f4240",
  "output": "0x"
}

The contract seems to be using OpenZeppelin's IERC20 that defines the return value as bool. Solidity now reverts when the expected output doesn't match the output returned by the contract.

There are a few popular EIP-20 tokens that were created before the final EIP-20 specs so they don't have a fully compliant contract, e.g. they return nothings instead of bool.

As a solution OpenZeppelin provides a library SafeERC20 that wraps calls to transfer and other methods to keep those contract working.

4
  • Thanks for the feedback Ismail. I implemented your suggestion & it worked perfectly.
    – Gobi Part
    Mar 16, 2022 at 9:03
  • though it fixed the issue but i can see using safeERC20 library have increased the fee to almost 57%. I found another fix for the issue through that i was able to compare the fee i. e interface IERC20 { function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external; } You can see that in the interface am declaring the transfer function in a way that it do not returns anything. It seems a hacky way but it utilizes less fee. Can you please suggest how may i reduce the fee using standard safeERC20 way.
    – Gobi Part
    Mar 22, 2022 at 3:11
  • @GobiPart That change will break EIP-20 compliant tokens. I doubt that's the real increase, if you see the code added it is pretty slim. Possible options are to downgrade solc to an older version, or make a low level call (in both cases you'll lose the security benefits in new solc versions).
    – Ismael
    Mar 22, 2022 at 16:39
  • @ismail it seems removing return from transfer function as i descibed earlier does not break ERC20 compliant tokens. More details i have asked/explained in this question ethereum.stackexchange.com/questions/124479/…. Could you please have a look ?
    – Gobi Part
    Mar 23, 2022 at 8:34

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.