Address Contract Verified
Address
0xeafc14e2Af750FF52C13349F13fA3A1bf9061497
Balance
0 ETH
Nonce
1
Code Size
3503 bytes
Creator
0xf36E5A9a...0797 at tx 0x469ab941...7e841b
Indexed Transactions
0
Contract Bytecode
3503 bytes
0x608080604052600436101561001357600080fd5b60003560e01c9081630f7921ed14610b34575080632e586cab14610a7a578063379607f5146108e2578063492daeac146105575780634bedf369146104c95780636aff4fbd1461034e5780638da5cb5b14610325578063b8152395146102d4578063b9ec526b146102b6578063c8972f311461027c578063e63ea408146101a8578063ef5d9ae81461016e5763f2fde38b146100ae57600080fd5b34610169576020366003190112610169576100c7610bbd565b600054906001600160a01b038216906100e1338314610c31565b6001600160a01b0316918215610128576001600160a01b031916821760009081557f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3005b60405162461bcd60e51b81526020600482015260196024820152784e6577206f776e6572206973207a65726f206164647265737360381b6044820152606490fd5b600080fd5b34610169576020366003190112610169576001600160a01b0361018f610bbd565b1660005260046020526020604060002054604051908152f35b34610169576060366003190112610169576101c1610bbd565b6024356001600160a01b0381169182820361016957604435916101ef60018060a01b03600054163314610c31565b83156102375781610224846020937ff24ef89f38eadc1bde50701ad6e4d6d11a2dc24f7cf834a486991f388332850495610c9a565b6040519384526001600160a01b031692a3005b60405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f7420776974686472617720746f207a65726f2061646472657373006044820152606490fd5b34610169576020366003190112610169576001600160a01b0361029d610bbd565b1660005260036020526020604060002054604051908152f35b34610169576000366003190112610169576020600154604051908152f35b3461016957602036600319011261016957602061031d6001600160a01b036102fa610bbd565b168060005260038352604060002054906000526004835260406000205490610c8d565b604051908152f35b34610169576000366003190112610169576000546040516001600160a01b039091168152602090f35b34610169576060366003190112610169576004356024356044359061037e60018060a01b03600054163314610c31565b82600052600260205260406000209060ff60048301541661046d577f8457997e1aebad9017da1580f22476860b49a185d33aa2e2b2be2a85564f91f0928260026080940192828454948260038501918254958883036103f4575b50505055604051938452602084015260408301526060820152a2005b88831115610437576104068984610c8d565b906001808060a01b0391015416600052600360205261042b6040600020918254610c24565b90555b55828a806103d8565b610441838a610c8d565b906001808060a01b039101541660005260036020526104666040600020918254610c8d565b905561042e565b60405162461bcd60e51b815260206004820152602e60248201527f416c726561647920636c61696d65642e2043616e6e6f7420757064617465206360448201526d3630b4b6b2b2103932b1b7b9321760911b6064820152608490fd5b3461016957602036600319011261016957600480356000908152600260208181526040928390208054600182015493820154600383015496830154600584015460069094015487516001600160a01b039485168152939096169483019490945294810194909452606084019490945260ff161515608083015260a082019290925260c081019190915260e090f35b34610169576080366003190112610169576004356001600160401b03811161016957610587903690600401610bd3565b6024356001600160401b038111610169576105a6903690600401610bd3565b6044356001600160401b038111610169576105c5903690600401610bd3565b9490916064356001600160401b038111610169576105e7903690600401610bd3565b9590936105ff60018060a01b03600054163314610c31565b828214806108d9575b806108d0575b156108935760005b82811061061f57005b600154600019811461087d57600101908160015561063e818a89610c69565b356212750081019283821161087d578b918a9161067f8561067861066d828d8f61066d8f849061067293610c69565b610c79565b98610c69565b9589610c69565b35936040519460e08601948686106001600160401b038711176108675760409586526001600160a01b0390811687529182166020808801918252878701928352606088018a8152600060808a0181815260a08b0182815260c08c01998a52978252600293849052989020985189549086166001600160a01b0319918216178a55925160018a01805491909616931692909217909355905191860191909155516003850155915160048401805460ff191691151560ff169190911790559051600583015551600690910155610754818b85610c69565b356001600160a01b0361076b61066d84898d610c69565b1660005260036020526107846040600020918254610c24565b90556001600160a01b0361079c61066d83878a610c69565b166000526005602052604060002091600154908354600160401b8110156108675760018101808655811015610851577f7c011f68b0ad48752bc63f93a5f632449876825ae3a0496c7e968001feb4e22160408e61082e878f9761066d8f978f8f61066d60019f610821926108279789968793600052602060002001556001549d610c69565b9b610c69565b928b610c69565b359482519586526020860152878060a01b031694878060a01b031693a401610616565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60405162461bcd60e51b8152602060048201526015602482015274082e4e4c2f240d8cadccee8d040dad2e6dac2e8c6d605b1b6044820152606490fd5b5086881461060e565b50878314610608565b3461016957602036600319011261016957600435600081815260026020526040902080546001600160a01b03163303610a445760038101544210610a085760048101805460ff81166109cf5760019060ff191617905560058101914283557f3e356ee9071ea983e847cc7da7b8b224b8f44262f7c9ce77262ea0e854a5442c60406002840194855494600181019560018060a01b03875416600052600460205261099184600020918254610c24565b9055855487546109ab9133906001600160a01b0316610c9a565b54945495549054825191825260208201526001600160a01b039586169590941693a4005b60405162461bcd60e51b815260206004820152601160248201527020b63932b0b23c903bb4ba34323930bbb760791b6044820152606490fd5b60405162461bcd60e51b81526020600482015260146024820152734e6f742074696d6520746f20776974686472617760601b6044820152606490fd5b60405162461bcd60e51b815260206004820152600e60248201526d2737ba1038bab2bab2903ab9b2b960911b6044820152606490fd5b34610169576020366003190112610169576001600160a01b03610a9b610bbd565b16600052600560205260406000206040518060208354918281520190819360005260206000209060005b818110610b1e5750505081610adb910382610c03565b6040519182916020830190602084525180915260408301919060005b818110610b05575050500390f35b8251845285945060209384019390920191600101610af7565b8254845260209093019260019283019201610ac5565b346101695760203660031901126101695760048035600090815260026020818152604092839020805460018201549382015460038301549683015460058401546006909401546001600160a01b039384168a52929095169388019390935293860191909152606085019390935260ff161515608084015260a083019190915260c082015260e090f35b600435906001600160a01b038216820361016957565b9181601f84011215610169578235916001600160401b038311610169576020808501948460051b01011161016957565b90601f801991011681019081106001600160401b0382111761086757604052565b9190820180921161087d57565b15610c3857565b60405162461bcd60e51b81526020600482015260096024820152682737ba1037bbb732b960b91b6044820152606490fd5b91908110156108515760051b0190565b356001600160a01b03811681036101695790565b9190820391821161087d57565b60405163a9059cbb60e01b81526001600160a01b039283166004820152602481019390935260209183916044918391600091165af1908115610d6d57600091610d2b575b5015610ce657565b60405162461bcd60e51b815260206004820152601d60248201527f536166655472616e736665723a207472616e73666572206661696c65640000006044820152606490fd5b6020813d602011610d65575b81610d4460209383610c03565b81010312610d615751908115158203610d5e575038610cde565b80fd5b5080fd5b3d9150610d37565b6040513d6000823e3d90fdfea2646970667358221220964205fce95a6e73c7fc9a81e63d04286939ac0401fa717f5f597e65531163ba64736f6c634300081c0033
Verified Source Code Full Match
Compiler: v0.8.28+commit.7893614a
EVM: paris
Optimization: Yes (20 runs)
WithdrawalQueue.sol 245 lines
// SPDX-License-Identifier: MIT
pragma solidity =0.8.28;
/**
* @dev 与标准 ERC20 类似,但仅包含 transfer,供演示用
*/
interface IERC20 {
function transfer(address recipient, uint256 amount) external returns (bool);
}
contract WithdrawalQueue {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event QueueAdded(
uint256 indexed queueId,
address indexed user,
address indexed token,
uint256 amount,
uint256 earliestWithdrawal
);
event Claimed(
uint256 indexed queueId,
address indexed user,
address indexed token,
uint256 amount,
uint256 claimTime
);
event QueueUpdated(
uint256 indexed queueId,
uint256 oldAmount,
uint256 newAmount,
uint256 oldEarliestWithdrawal,
uint256 newEarliestWithdrawal
);
event EmergencyWithdraw(address indexed token, address indexed to, uint256 amount);
address public owner;
/**
* @dev 提款队列信息
*/
struct QueueInfo {
address user;
address token;
uint256 amount;
uint256 earliestWithdrawal; // = requestTime + 14 days
bool claimed;
uint256 claimTime;
uint256 requestTime;
}
uint256 public currentQueueId;
// 队列ID => 队列信息
mapping(uint256 => QueueInfo) public queues;
// 统计每个 Token:
// totalAdded[token] = 通过 addWithdrawalQueueBatch() 添加的总量
// totalClaimed[token] = 已经被 claim() 领取的总量
mapping(address => uint256) public totalAdded;
mapping(address => uint256) public totalClaimed;
// 每个用户对应的所有队列 ID
mapping(address => uint256[]) private userQueueIds;
modifier onlyOwner() {
require(msg.sender == owner, "Not owner");
_;
}
constructor() {
owner = msg.sender;
}
function claim(uint256 claimId) external {
QueueInfo storage qInfo = queues[claimId];
require(qInfo.user == msg.sender, "Not queue user");
require(block.timestamp >= qInfo.earliestWithdrawal, "Not time to withdraw");
require(!qInfo.claimed, "Already withdrawn");
qInfo.claimed = true;
qInfo.claimTime = block.timestamp;
totalClaimed[qInfo.token] += qInfo.amount;
_safeTransfer(qInfo.token, msg.sender, qInfo.amount);
emit Claimed(
claimId,
qInfo.user,
qInfo.token,
qInfo.amount,
qInfo.claimTime
);
}
/**
* @dev 批量添加取款队列
* @param users 用户地址数组
* @param tokens Token 地址数组
* @param amounts 金额数组
* @param times 请求发起时间数组
*
* 注意:最早可提款时间 = 请求时间 + 14 days
*/
function addWithdrawalQueueBatch(
address[] calldata users,
address[] calldata tokens,
uint256[] calldata amounts,
uint256[] calldata times
) external onlyOwner {
require(
users.length == tokens.length &&
tokens.length == amounts.length &&
amounts.length == times.length,
"Array length mismatch"
);
for (uint256 i = 0; i < users.length; i++) {
currentQueueId++;
uint256 requestTime = times[i];
uint256 earliest = requestTime + 14 days;
queues[currentQueueId] = QueueInfo({
user: users[i],
token: tokens[i],
amount: amounts[i],
earliestWithdrawal: earliest,
claimed: false,
claimTime: 0,
requestTime: requestTime
});
totalAdded[tokens[i]] += amounts[i];
userQueueIds[users[i]].push(currentQueueId);
emit QueueAdded(
currentQueueId,
users[i],
tokens[i],
amounts[i],
earliest
);
}
}
function emergencyWithdraw(address token, address to, uint256 amount) external onlyOwner {
require(to != address(0), "Cannot withdraw to zero address");
_safeTransfer(token, to, amount);
emit EmergencyWithdraw(token, to, amount);
}
function updateQueueInfo(
uint256 claimId,
uint256 newAmount,
uint256 newEarliestWithdrawal
) external onlyOwner {
QueueInfo storage qInfo = queues[claimId];
require(!qInfo.claimed, "Already claimed. Cannot update claimed record.");
uint256 oldAmount = qInfo.amount;
uint256 oldEarliestWithdrawal = qInfo.earliestWithdrawal;
// 更新金额
if (newAmount != oldAmount) {
if (newAmount > oldAmount) {
totalAdded[qInfo.token] += (newAmount - oldAmount);
} else {
totalAdded[qInfo.token] -= (oldAmount - newAmount);
}
qInfo.amount = newAmount;
}
// 更新最早可领取时间
qInfo.earliestWithdrawal = newEarliestWithdrawal;
emit QueueUpdated(
claimId,
oldAmount,
newAmount,
oldEarliestWithdrawal,
newEarliestWithdrawal
);
}
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "New owner is zero address");
address oldOwner = owner;
owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
function getUserQueueIds(address user) external view returns (uint256[] memory) {
return userQueueIds[user];
}
/**
* @dev 获取某个 Token 剩余待领取的数量
*/
function getUnclaimedAmount(address token) external view returns (uint256) {
return totalAdded[token] - totalClaimed[token];
}
/**
* @dev 获取某个队列的详细信息
*/
function getQueueInfo(uint256 claimId)
external
view
returns (
address user,
address token,
uint256 amount,
uint256 earliestWithdrawal,
bool claimed,
uint256 claimTime,
uint256 requestTime
)
{
QueueInfo storage qInfo = queues[claimId];
return (
qInfo.user,
qInfo.token,
qInfo.amount,
qInfo.earliestWithdrawal,
qInfo.claimed,
qInfo.claimTime,
qInfo.requestTime
);
}
function _safeTransfer(address token, address to, uint256 amount) internal {
bool success = IERC20(token).transfer(to, amount);
require(success, "SafeTransfer: transfer failed");
}
}
Read Contract
currentQueueId 0xb9ec526b → uint256
getQueueInfo 0x4bedf369 → address, address, uint256, uint256, bool, uint256, uint256
getUnclaimedAmount 0xb8152395 → uint256
getUserQueueIds 0x2e586cab → uint256[]
owner 0x8da5cb5b → address
queues 0x0f7921ed → address, address, uint256, uint256, bool, uint256, uint256
totalAdded 0xc8972f31 → uint256
totalClaimed 0xef5d9ae8 → uint256
Write Contract 5 functions
These functions modify contract state and require a wallet transaction to execute.
addWithdrawalQueueBatch 0x492daeac
address[] users
address[] tokens
uint256[] amounts
uint256[] times
claim 0x379607f5
uint256 claimId
emergencyWithdraw 0xe63ea408
address token
address to
uint256 amount
transferOwnership 0xf2fde38b
address newOwner
updateQueueInfo 0x6aff4fbd
uint256 claimId
uint256 newAmount
uint256 newEarliestWithdrawal
Token Balances (1)
View Transfers →Recent Transactions
No transactions found for this address