Description:
Smart contract deployed on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IERC20 {
function balanceOf(address account) external view returns (uint256);
}
contract SimpleWallet {
address public owner;
event Received(address indexed sender, uint256 amount);
event Sent(address indexed to, uint256 amount);
event OwnerChanged(address indexed oldOwner, address indexed newOwner);
event ERC20Sent(address indexed token, address indexed to, uint256 amount);
event ERC20Recovered(address indexed token, address indexed to, uint256 amount);
modifier onlyOwner() {
require(msg.sender == owner, "not owner");
_;
}
bool private locked;
modifier noReentrant() {
require(!locked, "reentrant");
locked = true;
_;
locked = false;
}
constructor(address _owner) {
require(_owner != address(0), "zero owner");
owner = _owner;
}
receive() external payable {
emit Received(msg.sender, msg.value);
}
fallback() external payable {
emit Received(msg.sender, msg.value);
}
function balance() external view returns (uint256) {
return address(this).balance;
}
function changeOwner(address newOwner) external onlyOwner {
require(newOwner != address(0), "zero new owner");
emit OwnerChanged(owner, newOwner);
owner = newOwner;
}
function sendEther(address payable to, uint256 amount) external onlyOwner noReentrant returns (bool) {
require(to != address(0), "zero to");
require(address(this).balance >= amount, "insufficient balance");
(bool ok, ) = to.call{value: amount}("");
require(ok, "send failed");
emit Sent(to, amount);
return ok;
}
/// -----------------
/// ✅ 批量 ETH 转账
/// -----------------
function batchSendEther(address payable[] calldata to, uint256[] calldata amounts)
external onlyOwner noReentrant returns (bool)
{
require(to.length == amounts.length, "array length mismatch");
for (uint256 i = 0; i < to.length; i++) {
require(to[i] != address(0), "zero to");
require(address(this).balance >= amounts[i], "insufficient balance");
(bool ok, ) = to[i].call{value: amounts[i]}("");
require(ok, "send failed");
emit Sent(to[i], amounts[i]);
}
return true;
}
function withdrawAll() external onlyOwner noReentrant returns (bool) {
uint256 bal = address(this).balance;
require(bal > 0, "no balance");
(bool ok, ) = payable(owner).call{value: bal}("");
require(ok, "withdraw failed");
emit Sent(owner, bal);
return ok;
}
function sendERC20(address token, address to, uint256 amount) external onlyOwner noReentrant returns (bool) {
require(token != address(0), "zero token");
require(to != address(0), "zero to");
require(amount > 0, "zero amount");
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, amount));
require(success && (data.length == 0 || abi.decode(data, (bool))), "ERC20: transfer failed");
emit ERC20Sent(token, to, amount);
return true;
}
/// -----------------
/// ✅ 批量 ERC20 转账
/// -----------------
function batchSendERC20(address token, address[] calldata to, uint256[] calldata amounts)
external onlyOwner noReentrant returns (bool)
{
require(token != address(0), "zero token");
require(to.length == amounts.length, "array length mismatch");
for (uint256 i = 0; i < to.length; i++) {
require(to[i] != address(0), "zero to");
require(amounts[i] > 0, "zero amount");
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to[i], amounts[i]));
require(success && (data.length == 0 || abi.decode(data, (bool))), "ERC20: transfer failed");
emit ERC20Sent(token, to[i], amounts[i]);
}
return true;
}
function recoverERC20(address token) external onlyOwner noReentrant returns (bool) {
require(token != address(0), "zero token");
uint256 bal = IERC20(token).balanceOf(address(this));
require(bal > 0, "no token balance");
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, owner, bal));
require(success && (data.length == 0 || abi.decode(data, (bool))), "ERC20: recover failed");
emit ERC20Recovered(token, owner, bal);
return true;
}
function tokenBalance(address token) external view returns (uint256) {
if (token == address(0)) return 0;
return IERC20(token).balanceOf(address(this));
}
}
Submitted on: 2025-09-25 13:50:25
Comments
Log in to comment.
No comments yet.