Sending payments in bulk can be a tedious and time-consuming process, especially when dealing with a large number of recipients. However, with a Solidity smart contract, bulk payments can be executed in a matter of seconds, providing a more efficient and cost-effective solution for managing bulk transfers.
In this article, I will walk you through the process of how to bulk send payments on Ethereum using a contract in Solidity.
Step 1: Set Up the Contract
We are going to be using this contract which I will walk through as an example: https://github.com/jamesbachini/Solidity-Snippets/blob/main/contracts/BulkSend.sol
After importing some standard OpenZeppelin libraries we start by defining our state variables
address token = 0x2f3A40A3db8a7e3D09B0adfEfbCe4f6F81927557;
uint tokenAmount = 5000 * 1e6; // 5000 tokens
uint ethAmount = 5000000000000000; // 0.005 ETH
The token is a contract address for the token which you can find using etherscan. Note that contract addresses differ depending on which chain you are on so make sure you have the right one. Also if you are getting errors make sure the contract address isn’t all lowercase because this breaks the checksum.
Next we define a token amount, note that we are using USDC here which has 6 decimals whereas most tokens have 18. If you were using something standard you would use this code:
uint tokenAmount = 5000 * 1e18; // 5000 tokens
Finally we define an ETH amount, quite unelegantly, which equates to 0.005 ETH. Note that this contract sends out both ETH and tokens so you may want to adapt it to suit your requirements.
We then have a function to send out the tokens to an array of users
function sendOutFunds(address[] memory _to) public onlyOwner {
for (uint i = 0; i < _to.length; i++) {
IERC20(token).transfer(_to[i], tokenAmount);
payable(_to[i]).transfer(ethAmount);
}
}
We pass an array of Ethereum addresses [0x…,0x…,0x…] into the function and it loops over them sending out the funds. The IERC20 line sends out tokens and the payable line sends out ETH, comment out accordingly if you only want to send one or the other.
Finally we have a withdraw() and reclaimTokens() function to get back any left over funds in the contract.
Step 2. Deploy Using Remix
We can then deploy the code using remix at https://remix.ethereum.org
Copy and paste the code in, change the values and/or token contract address in the state variables. Then compile and deploy the code using Metamask to a testnet initially to ensure it works as expected.
Once deployed we will need to load up the contract with funds to send out.
Step 3. Load Contract & Send Funds
Note that there are a lot of scams and it’s always best to fully understand the code you are deploying and test it on a testnet before using with real funds.
Before running the sendOutFunds() function we need to send the contract the funds to send out. We can do this by simply transfering either ERC20 tokens or ether to the recently deployed contract address.
In remix you’ll see a section where you can copy the contract address (0XD58…E350D) and expand it down to see all the functions:
The final step is to format your list of addresses into a comma separated array like so:
[0x123…,0x132…,0x123]
and pass this into the sendOutFunds(address[]); function. Note that this can only be called by the same wallet address that deployed the contract.
Once done you can use the withdraw function to return any remaining ETH assuming it covers gas fees and the reclaimToken(tokenContractAddress) to get back any left over ERC20 tokens.
Conclusion
This simple smart contract provides an easy but extendable way to send out multiple different types of funds to hundreds of users in a single transaction. This is great for airdrops, giveaways and payroll type systems as it reduces the gas costs and transactional volume of doing them individually.
Solidity provides us with a way to use this programmable money and build on top of existing tokens, protocols and scripts to create unique products. I hope this tutorial has been of interest and it serves as a good introduction to sending payments and transferring funds within solidity smart contracts.