HoodDisperse
0x655f30299a3f6eece880b313fce76ef6fcb88c11
Verification
Verified
v0.8.20+commit.a1b79de6
Type
Contract
4,299 bytes
ABI entries
14
3 read · 5 write
License
none
Contract information
- Address
- 0x655f30299a3f6eece880b313fce76ef6fcb88c11
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.20+commit.a1b79de6
- Optimization
- Enabled
- Creator
- 0x3b105A2049…Ef6304d0e8
- Creation tx
- 0x6a54d564b0…c18be8d92e
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (3)
feePerBatch() → uint256
getFee() → uint256
owner() → address
Events (4)
EthDispersedFeeCollectedFeeUpdatedTokenDispersed
ABI
[
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "totalRecipients",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "totalAmount",
"type": "uint256"
}
],
"name": "EthDispersed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "payer",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "FeeCollected",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "oldFee",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newFee",
"type": "uint256"
}
],
"name": "FeeUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "totalRecipients",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "totalAmount",
"type": "uint256"
}
],
"name": "TokenDispersed",
"type": "event"
},
{
"inputs": [
{
"internalType": "address[]",
"name": "recipients",
"type": "address[]"
},
{
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
}
],
"name": "disperseEth",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "address[]",
"name": "recipients",
"type": "address[]"
},
{
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
}
],
"name": "disperseToken",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "feePerBatch",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getFee",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newFee",
"type": "uint256"
}
],
"name": "setFee",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "withdrawEth",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
}
],
"name": "withdrawToken",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC20 {
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
}
contract HoodDisperse {
address public owner;
uint256 public feePerBatch = 0.00005 ether;
event EthDispersed(uint256 totalRecipients, uint256 totalAmount);
event TokenDispersed(address indexed token, uint256 totalRecipients, uint256 totalAmount);
event FeeCollected(address indexed payer, uint256 amount);
event FeeUpdated(uint256 oldFee, uint256 newFee);
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
function setFee(uint256 newFee) external onlyOwner {
emit FeeUpdated(feePerBatch, newFee);
feePerBatch = newFee;
}
function disperseEth(
address[] calldata recipients,
uint256[] calldata amounts
) external payable {
require(recipients.length == amounts.length, "Length mismatch");
require(recipients.length > 0, "Empty list");
require(recipients.length <= 500, "Max 500 per batch");
uint256 totalAirdrop = 0;
for (uint256 i = 0; i < amounts.length; i++) {
totalAirdrop += amounts[i];
}
require(
msg.value >= feePerBatch + totalAirdrop,
"Insufficient ETH: fee + amounts required"
);
(bool feeSent, ) = owner.call{value: feePerBatch}("");
require(feeSent, "Fee transfer failed");
emit FeeCollected(msg.sender, feePerBatch);
for (uint256 i = 0; i < recipients.length; i++) {
require(recipients[i] != address(0), "Zero address");
(bool success, ) = recipients[i].call{value: amounts[i]}("");
require(success, "ETH transfer failed");
}
uint256 leftover = msg.value - feePerBatch - totalAirdrop;
if (leftover > 0) {
(bool refund, ) = msg.sender.call{value: leftover}("");
require(refund, "Refund failed");
}
emit EthDispersed(recipients.length, totalAirdrop);
}
function disperseToken(
address token,
address[] calldata recipients,
uint256[] calldata amounts
) external payable {
require(recipients.length == amounts.length, "Length mismatch");
require(recipients.length > 0, "Empty list");
require(recipients.length <= 500, "Max 500 per batch");
require(token != address(0), "Invalid token");
require(msg.value >= feePerBatch, "Insufficient fee");
(bool feeSent, ) = owner.call{value: feePerBatch}("");
require(feeSent, "Fee transfer failed");
emit FeeCollected(msg.sender, feePerBatch);
IERC20 erc20 = IERC20(token);
uint256 total = 0;
for (uint256 i = 0; i < amounts.length; i++) {
total += amounts[i];
}
require(
erc20.allowance(msg.sender, address(this)) >= total,
"Insufficient allowance"
);
for (uint256 i = 0; i < recipients.length; i++) {
require(recipients[i] != address(0), "Zero address");
bool success = erc20.transferFrom(
msg.sender,
recipients[i],
amounts[i]
);
require(success, "Token transfer failed");
}
uint256 leftover = msg.value - feePerBatch;
if (leftover > 0) {
(bool refund, ) = msg.sender.call{value: leftover}("");
require(refund, "Refund failed");
}
emit TokenDispersed(token, recipients.length, total);
}
function withdrawEth() external onlyOwner {
uint256 bal = address(this).balance;
require(bal > 0, "Nothing to withdraw");
(bool ok, ) = owner.call{value: bal}("");
require(ok, "Withdraw failed");
}
function withdrawToken(address token) external onlyOwner {
IERC20 erc20 = IERC20(token);
uint256 bal = erc20.balanceOf(address(this));
require(bal > 0, "No tokens");
erc20.transfer(owner, bal);
}
function getFee() external view returns (uint256) {
return feePerBatch;
}
receive() external payable {}
}Chain explorer2467msChain node87ms