# Is this a gas efficient way to send ERC20 tokens?

**URL:** <https://forum.openzeppelin.com/t/is-this-a-gas-efficient-way-to-send-erc20-tokens/13386>\
**Category:** Review Wanted\
**Tags:** erc20, gas\
**Created:** [August 1, 2021, 6:57pm UTC](https://forum.openzeppelin.com/t/is-this-a-gas-efficient-way-to-send-erc20-tokens/13386 "2021-08-01T18:57:04Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![tedoshij](https://avatars.discourse-cdn.com/v4/letter/t/ecc23a/32.png) [@tedoshij](https://forum.openzeppelin.com/u/tedoshij)\
**Post date:** [August 1, 2021, 6:57pm UTC](https://forum.openzeppelin.com/t/is-this-a-gas-efficient-way-to-send-erc20-tokens/13386/1 "2021-08-01T18:57:04Z")

</div>

Hello, Using ERC20 from OpenZepplin Wizard to create an ERC20 token.  
We want the ability to send this token to several addresses at once on occasion.

Will this function **sendBatchMyToken** accomplish the goal of reducing gas costs?

Any other suggestions to improve this code are very welcome. Thank you

```auto
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {

    constructor() ERC20("MyToken", "MTC") payable {
        _mint(msg.sender, 1000 * 10 ** decimals());     
		// test wallet1
        _transfer(msg.sender, 0xAb8483F64d9C6d1EcF9b859Ae677dD3315835cb2, 50 * 10 ** 18);       
        
    }
    event BatchTransferMyToken(address indexed _caller, uint256 _recipientCount, uint256 _totalTokensSent);    
    
	// 
    function sendBatchMyToken(address[] calldata walletAddresses, uint256[] calldata sendAmounts) payable external returns (bool) {
        uint256 walletCount = walletAddresses.length;
        require(walletCount == sendAmounts.length, "Check length of walletAddresses / sendAmounts arrays.");
        uint256 senderBalance = balanceOf(msg.sender);
        uint256 totalSentMyToken = 0;
        uint256 sendAmount;
        uint256 decimalPlaces = 10 ** 18;
        for(uint i = 0; i < walletCount; i++) {
            sendAmount = sendAmounts[i] * decimalPlaces;
            require(sendAmount <= senderBalance, "Sending more then sender has remaining.");
            _transfer(msg.sender, walletAddresses[i], sendAmount);
            totalSentMyToken = totalSentMyToken + sendAmount;
            senderBalance = senderBalance - sendAmount;
        }
        emit BatchTransferMyToken(msg.sender, walletAddresses.length, totalSentMyToken);
        return true;
    } 

}

```

---

<div class="post-metadata">

**Author:** ![tedoshij](https://avatars.discourse-cdn.com/v4/letter/t/ecc23a/32.png) [@tedoshij](https://forum.openzeppelin.com/u/tedoshij)\
**Post date:** [August 1, 2021, 7:08pm UTC](https://forum.openzeppelin.com/t/is-this-a-gas-efficient-way-to-send-erc20-tokens/13386/2 "2021-08-01T19:08:11Z")

</div>

When sending the same value we will use this function:

```auto
    function sendBatchMyTokenSameValue(address[] calldata walletAddresses, uint256 sendValue) payable external returns (bool) {
        uint256 walletCount = walletAddresses.length;
        uint256 senderBalance = balanceOf(msg.sender);
        uint256 totalSentMyToken = 0;
        uint256 sendAmount = sendValue * 10 ** 18;
        
        for(uint i = 0; i < walletCount; i++) {
            require(sendAmount <= senderBalance, "Sending more then sender has remaining.");
            _transfer(msg.sender, walletAddresses[i], sendAmount);
            totalSentMyToken = totalSentMyToken + sendAmount;
            senderBalance = senderBalance - sendAmount;
        }
        emit BatchTransferMyToken(msg.sender, walletAddresses.length, totalSentMyToken);
        return true;
    } 

```

---

<div class="post-metadata">

**Author:** ![maxareo](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/maxareo/32/11606_2.png) [@maxareo](https://forum.openzeppelin.com/u/maxareo)\
**Post date:** [August 3, 2021, 2:44am UTC](https://forum.openzeppelin.com/t/is-this-a-gas-efficient-way-to-send-erc20-tokens/13386/3 "2021-08-03T02:44:57Z")

</div>

The same question was asked before [here](https://forum.openzeppelin.com/t/erc20-batchtransfer-functionality/6978/5), and a recommended approach there was to use `multicall`.
