diff --git a/packages/addresses/src/addresses.athens.json b/packages/addresses/src/addresses.athens.json index 413e3a2d..1a408b1d 100644 --- a/packages/addresses/src/addresses.athens.json +++ b/packages/addresses/src/addresses.athens.json @@ -4,6 +4,7 @@ "crossChainCounter": "", "crossChainNft": "", "dai": "", + "disperse": "", "immutableCreate2Factory": "0x095a03c6a68137fE9a566bBc3e552F299d8b886d", "multiChainSwap": "0x8BD7144Ddb59c9Fa3Dcf809998521E9cAD946fa1", "multiChainSwapZetaConnector": "", @@ -30,6 +31,7 @@ "crossChainCounter": "", "crossChainNft": "", "dai": "", + "disperse": "", "immutableCreate2Factory": "0x095a03c6a68137fE9a566bBc3e552F299d8b886d", "multiChainSwap": "0x323745f16C93e56a98012970c28788498d8B3a14", "multiChainSwapZetaConnector": "", @@ -82,6 +84,7 @@ "crossChainCounter": "", "crossChainNft": "", "dai": "", + "disperse": "", "immutableCreate2Factory": "", "multiChainSwap": "", "multiChainValue": "", @@ -107,6 +110,7 @@ "crossChainCounter": "", "crossChainNft": "", "dai": "", + "disperse": "0x1E0F767F48Fb10FcF820703f116E9B0F87319d63", "immutableCreate2Factory": "", "multiChainSwap": "", "multiChainSwapZetaConnector": "", @@ -133,6 +137,7 @@ "crossChainCounter": "", "crossChainNft": "", "dai": "", + "disperse": "", "immutableCreate2Factory": "", "multiChainSwap": "", "multiChainSwapZetaConnector": "", diff --git a/packages/addresses/src/addresses.helpers.ts b/packages/addresses/src/addresses.helpers.ts index e3a21f84..330bd00f 100644 --- a/packages/addresses/src/addresses.helpers.ts +++ b/packages/addresses/src/addresses.helpers.ts @@ -7,6 +7,7 @@ export type ZetaAddress = | "crossChainCounter" | "crossChainNft" | "dai" + | "disperse" | "immutableCreate2Factory" | "multiChainSwap" | "multiChainSwapZetaConnector" @@ -34,6 +35,7 @@ const zetaAddresses: Record = { crossChainCounter: true, crossChainNft: true, dai: true, + disperse: true, immutableCreate2Factory: true, multiChainSwap: true, multiChainSwapZetaConnector: true, diff --git a/packages/zevm-app-contracts/contracts/disperse/Disperse.sol b/packages/zevm-app-contracts/contracts/disperse/Disperse.sol new file mode 100644 index 00000000..9adc5cec --- /dev/null +++ b/packages/zevm-app-contracts/contracts/disperse/Disperse.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.7; + +import "@openzeppelin/contracts/interfaces/IERC20.sol"; + +contract Disperse { + function disperseEther(address[] calldata recipients, uint256[] calldata values) external payable { + for (uint256 i = 0; i < recipients.length; i++) payable(recipients[i]).transfer(values[i]); + uint256 balance = address(this).balance; + if (balance > 0) payable(msg.sender).transfer(balance); + } + + function disperseToken(IERC20 token, address[] calldata recipients, uint256[] calldata values) external { + uint256 total = 0; + for (uint256 i = 0; i < recipients.length; i++) total += values[i]; + require(token.transferFrom(msg.sender, address(this), total)); + for (uint256 i = 0; i < recipients.length; i++) require(token.transfer(recipients[i], values[i])); + } + + function disperseTokenSimple(IERC20 token, address[] calldata recipients, uint256[] calldata values) external { + for (uint256 i = 0; i < recipients.length; i++) + require(token.transferFrom(msg.sender, recipients[i], values[i])); + } +} diff --git a/packages/zevm-app-contracts/scripts/disperse/deploy.ts b/packages/zevm-app-contracts/scripts/disperse/deploy.ts new file mode 100644 index 00000000..8b8a28b7 --- /dev/null +++ b/packages/zevm-app-contracts/scripts/disperse/deploy.ts @@ -0,0 +1,23 @@ +import { isNetworkName } from "@zetachain/addresses"; +import { saveAddress } from "@zetachain/addresses-tools"; +import { ethers, network } from "hardhat"; + +import { Disperse__factory } from "../../typechain-types"; + +const networkName = network.name; + +async function main() { + if (!isNetworkName(networkName)) throw new Error("Invalid network name"); + + const DisperseFactory = (await ethers.getContractFactory("Disperse")) as Disperse__factory; + + const disperseFactory = await DisperseFactory.deploy(); + await disperseFactory.deployed(); + console.log("Disperse deployed to:", disperseFactory.address); + saveAddress("disperse", disperseFactory.address); +} + +main().catch(error => { + console.error(error); + process.exit(1); +});