编译器
0.8.23+commit.f704f362
文件 1 的 5:BatchClaimV2.sol
pragma solidity ^0.8.23;
import {EnumerableSet} from "node_modules/@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {Ownable} from "node_modules/@openzeppelin/contracts/access/Ownable.sol";
import {IClaimVault} from "../interfaces/IClaimVault.sol";
contract BatchClaimV2 is Ownable {
using EnumerableSet for EnumerableSet.AddressSet;
EnumerableSet.AddressSet internal _enabledUsers;
mapping(address => mapping(address => bool)) public userLSTConfig;
IClaimVault public claimVault;
address public scheduler;
event ClaimFailed(address indexed user, address indexed lst, string reason);
event AutoClaimEnabled(address indexed user, address indexed lst);
event AutoClaimDisabled(address indexed user, address indexed lst);
event ClaimVaultUpdated(address indexed newClaimVault);
constructor(address _claimVault) Ownable(msg.sender) {
require(_claimVault != address(0), "Rewards tracker address cannot be the zero address");
claimVault = IClaimVault(_claimVault);
}
modifier onlyScheduler() {
require(msg.sender == owner() || msg.sender == scheduler, "BatchClaim: Caller is not authorized");
_;
}
function setAutoClaim(address lst, bool _enabled) external {
_setAutoClaim(msg.sender, lst, _enabled);
}
function isAutoClaimEnabled(address lst, address _user) external view returns (bool) {
return userLSTConfig[_user][lst];
}
function getAutoClaimUsers() external view returns (address[] memory) {
return _enabledUsers.values();
}
function setScheduler(address _scheduler) external onlyOwner {
require(_scheduler != address(0), "BatchClaim: Scheduler address cannot be the zero address");
scheduler = _scheduler;
}
function updateClaimVault(address _newClaimVault) external onlyOwner {
require(_newClaimVault != address(0), "BatchClaim: ClaimVault address cannot be the zero address");
claimVault = IClaimVault(_newClaimVault);
emit ClaimVaultUpdated(_newClaimVault);
}
function batchClaim() external onlyScheduler {
address[] memory lsts = claimVault.getLSTs();
uint256 userLength = _enabledUsers.length();
uint256 lstLength = lsts.length;
for (uint256 i; i < userLength; ++i) {
address user = _enabledUsers.at(i);
for (uint256 j; j < lstLength; ++j) {
if (userLSTConfig[user][lsts[j]]) {
claimRewardsFor(lsts[j], user);
}
}
}
}
function multiClaim(address[] calldata _users) external onlyScheduler {
address[] memory lsts = claimVault.getLSTs();
uint256 userLength = _users.length;
uint256 lstLength = lsts.length;
for (uint256 i; i < userLength; ++i) {
address user = _users[i];
for (uint256 j; j < lstLength; ++j) {
if (userLSTConfig[user][lsts[j]]) {
claimRewardsFor(lsts[j], user);
}
}
}
}
function multiClaimLST(address lst, address[] calldata _users) external onlyScheduler {
uint256 userLength = _users.length;
for (uint256 i; i < userLength; ++i) {
if (userLSTConfig[_users[i]][lst]) {
claimRewardsFor(lst, _users[i]);
}
}
}
function setAutoClaimForUser(address user, address lst, bool _enabled) external onlyOwner {
_setAutoClaim(user, lst, _enabled);
}
function _setAutoClaim(address user, address lst, bool _enabled) internal {
address[] memory lsts = claimVault.getLSTs();
bool validLST = false;
uint256 lstLength = lsts.length;
for (uint i; i < lstLength; ++i) {
if (lst == lsts[i]) {
validLST = true;
break;
}
}
require(validLST, "BatchClaim: LST not found");
userLSTConfig[user][lst] = _enabled;
if (_enabled) {
if (!_enabledUsers.contains(user)) {
_enabledUsers.add(user);
}
emit AutoClaimEnabled(user, lst);
} else {
bool remove = true;
for (uint i; i < lstLength; ++i) {
if (userLSTConfig[user][lsts[i]]) {
remove = false;
break;
}
}
if (remove) {
_enabledUsers.remove(user);
}
emit AutoClaimDisabled(user, lst);
}
}
function claimRewardsFor(address lst, address user) internal {
try claimVault.claimRewardsFor(lst, user) {
} catch Error(string memory reason) {
emit ClaimFailed(user, lst, reason);
} catch {
emit ClaimFailed(user, lst, "Unknown error");
}
}
}
文件 2 的 5:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 3 的 5:EnumerableSet.sol
pragma solidity ^0.8.20;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping(bytes32 value => uint256) _positions;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 position = set._positions[value];
if (position != 0) {
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
set._values[valueIndex] = lastValue;
set._positions[lastValue] = position;
}
set._values.pop();
delete set._positions[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
assembly {
result := store
}
return result;
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly {
result := store
}
return result;
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly {
result := store
}
return result;
}
}
文件 4 的 5:IClaimVault.sol
pragma solidity ^0.8.23;
interface IClaimVault {
function claimRewards(address lst) external;
function claimRewardsFor(address lst, address user) external;
function getLSTs() external view returns (address[] memory);
}
文件 5 的 5:Ownable.sol
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
error OwnableUnauthorizedAccount(address account);
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
{
"compilationTarget": {
"src/rewards/BatchClaimV2.sol": "BatchClaimV2"
},
"evmVersion": "paris",
"libraries": {
":__CACHE_BREAKER__": "0x0000000000000031373239353934323535333231"
},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 1000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_claimVault","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"lst","type":"address"}],"name":"AutoClaimDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"lst","type":"address"}],"name":"AutoClaimEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"lst","type":"address"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"ClaimFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newClaimVault","type":"address"}],"name":"ClaimVaultUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"batchClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimVault","outputs":[{"internalType":"contract IClaimVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAutoClaimUsers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lst","type":"address"},{"internalType":"address","name":"_user","type":"address"}],"name":"isAutoClaimEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"multiClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"lst","type":"address"},{"internalType":"address[]","name":"_users","type":"address[]"}],"name":"multiClaimLST","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"scheduler","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lst","type":"address"},{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setAutoClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"address","name":"lst","type":"address"},{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setAutoClaimForUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_scheduler","type":"address"}],"name":"setScheduler","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newClaimVault","type":"address"}],"name":"updateClaimVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userLSTConfig","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]