Address Contract Verified
Address
0x0e72Bb46d8Bf1Ba0DA82F129517a91d235458774
Balance
0 ETH
Nonce
1
Code Size
5347 bytes
Creator
0x9e3c17d3...C228 at tx 0xa8411644...47174d
Indexed Transactions
0
Contract Bytecode
5347 bytes
0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80638bc1d63911610097578063c74cd01411610066578063c74cd01414610206578063d1ad17bf14610219578063f2fde38b1461022c578063f4af0bd01461023f57600080fd5b80638bc1d6391461018d5780638da5cb5b146101a0578063a0960281146101c5578063ab518e6e146101f357600080fd5b806340a0b4ec116100d357806340a0b4ec1461014c578063610374a51461015f578063715018a61461017257806385524efc1461017a57600080fd5b806307a38851146100fa57806310078eb3146101225780633f6746ce14610137575b600080fd5b61010d61010836600461105e565b610247565b60405190151581526020015b60405180910390f35b61012a610277565b6040516101199190611097565b61014a6101453660046110e4565b610288565b005b61014a61015a3660046110e4565b610340565b61014a61016d36600461114d565b61041b565b61014a61053e565b61014a6101883660046111b7565b610552565b61014a61019b3660046111fe565b61056a565b6000546001600160a01b03165b6040516001600160a01b039091168152602001610119565b61010d6101d336600461105e565b600360209081526000928352604080842090915290825290205460ff1681565b6004546101ad906001600160a01b031681565b61014a610214366004611233565b610579565b6005546101ad906001600160a01b031681565b61014a61023a3660046110e4565b610751565b61014a6107a8565b6001600160a01b0380821660009081526003602090815260408083209386168352929052205460ff165b92915050565b60606102836001610960565b905090565b610290610974565b6001600160a01b0381166103115760405162461bcd60e51b815260206004820152603860248201527f4261746368436c61696d3a205363686564756c6572206164647265737320636160448201527f6e6e6f7420626520746865207a65726f2061646472657373000000000000000060648201526084015b60405180910390fd5b6005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b610348610974565b6001600160a01b0381166103c45760405162461bcd60e51b815260206004820152603960248201527f4261746368436c61696d3a20436c61696d5661756c742061646472657373206360448201527f616e6e6f7420626520746865207a65726f2061646472657373000000000000006064820152608401610308565b6004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517fe8be4a3b4254e4bf5ece73e698ebf93c5d0e46b71dcb1375e8165b6884e10f3e90600090a250565b6000546001600160a01b031633148061043e57506005546001600160a01b031633145b6104965760405162461bcd60e51b8152602060048201526024808201527f4261746368436c61696d3a2043616c6c6572206973206e6f7420617574686f726044820152631a5e995960e21b6064820152608401610308565b8060005b8181101561053757600360008585848181106104b8576104b8611275565b90506020020160208101906104cd91906110e4565b6001600160a01b039081168252602080830193909352604091820160009081209189168152925290205460ff161561052f5761052f8585858481811061051557610515611275565b905060200201602081019061052a91906110e4565b6109ba565b60010161049a565b5050505050565b610546610974565b6105506000610b31565b565b61055a610974565b610565838383610b8e565b505050565b610575338383610b8e565b5050565b6000546001600160a01b031633148061059c57506005546001600160a01b031633145b6105f45760405162461bcd60e51b8152602060048201526024808201527f4261746368436c61696d3a2043616c6c6572206973206e6f7420617574686f726044820152631a5e995960e21b6064820152608401610308565b6000600460009054906101000a90046001600160a01b03166001600160a01b03166308437d156040518163ffffffff1660e01b8152600401600060405180830381865afa158015610649573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261067191908101906112ce565b8051909150829060005b8281101561074957600086868381811061069757610697611275565b90506020020160208101906106ac91906110e4565b905060005b8381101561073f576001600160a01b038216600090815260036020526040812087519091908890849081106106e8576106e8611275565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16156107375761073786828151811061072957610729611275565b6020026020010151836109ba565b6001016106b1565b505060010161067b565b505050505050565b610759610974565b6001600160a01b03811661079c576040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260006004820152602401610308565b6107a581610b31565b50565b6000546001600160a01b03163314806107cb57506005546001600160a01b031633145b6108235760405162461bcd60e51b8152602060048201526024808201527f4261746368436c61696d3a2043616c6c6572206973206e6f7420617574686f726044820152631a5e995960e21b6064820152608401610308565b6000600460009054906101000a90046001600160a01b03166001600160a01b03166308437d156040518163ffffffff1660e01b8152600401600060405180830381865afa158015610878573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108a091908101906112ce565b905060006108ae6001610e1f565b825190915060005b8281101561095a5760006108cb600183610e29565b905060005b83811015610950576001600160a01b0382166000908152600360205260408120875190919088908490811061090757610907611275565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16156109485761094886828151811061072957610729611275565b6001016108d0565b50506001016108b6565b50505050565b6060600061096d83610e35565b9392505050565b6000546001600160a01b03163314610550576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610308565b600480546040517fa16633400000000000000000000000000000000000000000000000000000000081526001600160a01b0385811693820193909352838316602482015291169063a166334090604401600060405180830381600087803b158015610a2457600080fd5b505af1925050508015610a35575060015b61057557610a41611381565b806308c379a003610ab05750610a5561139d565b80610a605750610ab2565b826001600160a01b0316826001600160a01b03167f941d4080bf45ad4f4b547a2c095bc203ff76ba1f67d7e1102d7059f686d617c883604051610aa39190611427565b60405180910390a3505050565b505b816001600160a01b0316816001600160a01b03167f941d4080bf45ad4f4b547a2c095bc203ff76ba1f67d7e1102d7059f686d617c8604051610b25906020808252600d908201527f556e6b6e6f776e206572726f7200000000000000000000000000000000000000604082015260600190565b60405180910390a35050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000600460009054906101000a90046001600160a01b03166001600160a01b03166308437d156040518163ffffffff1660e01b8152600401600060405180830381865afa158015610be3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c0b91908101906112ce565b8051909150600090815b81811015610c6057838181518110610c2f57610c2f611275565b60200260200101516001600160a01b0316866001600160a01b031603610c585760019250610c60565b600101610c15565b5081610cae5760405162461bcd60e51b815260206004820152601960248201527f4261746368436c61696d3a204c5354206e6f7420666f756e64000000000000006044820152606401610308565b6001600160a01b038681166000908152600360209081526040808320938916835292905220805460ff19168515801591909117909155610d4957610cf3600187610e91565b610d0457610d02600187610eb3565b505b846001600160a01b0316866001600160a01b03167f68a0e1fb4b8d8347cf019e12fe88923b558d51953a8a42bbb3fe0040de5c775260405160405180910390a3610749565b600160005b82811015610dc2576001600160a01b03881660009081526003602052604081208651909190879084908110610d8557610d85611275565b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff1615610dba5760009150610dc2565b600101610d4e565b508015610dd657610dd4600188610ec8565b505b856001600160a01b0316876001600160a01b03167f67b5a7964c73c3b4f79389396f8318446f36c5e4faa5efafb71e299a8d95393360405160405180910390a350505050505050565b6000610271825490565b600061096d8383610edd565b606081600001805480602002602001604051908101604052809291908181526020018280548015610e8557602002820191906000526020600020905b815481526020019060010190808311610e71575b50505050509050919050565b6001600160a01b0381166000908152600183016020526040812054151561096d565b600061096d836001600160a01b038416610f07565b600061096d836001600160a01b038416610f56565b6000826000018281548110610ef457610ef4611275565b9060005260206000200154905092915050565b6000818152600183016020526040812054610f4e57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610271565b506000610271565b6000818152600183016020526040812054801561103f576000610f7a600183611476565b8554909150600090610f8e90600190611476565b9050808214610ff3576000866000018281548110610fae57610fae611275565b9060005260206000200154905080876000018481548110610fd157610fd1611275565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061100457611004611497565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610271565b6000915050610271565b6001600160a01b03811681146107a557600080fd5b6000806040838503121561107157600080fd5b823561107c81611049565b9150602083013561108c81611049565b809150509250929050565b6020808252825182820181905260009190848201906040850190845b818110156110d85783516001600160a01b0316835292840192918401916001016110b3565b50909695505050505050565b6000602082840312156110f657600080fd5b813561096d81611049565b60008083601f84011261111357600080fd5b50813567ffffffffffffffff81111561112b57600080fd5b6020830191508360208260051b850101111561114657600080fd5b9250929050565b60008060006040848603121561116257600080fd5b833561116d81611049565b9250602084013567ffffffffffffffff81111561118957600080fd5b61119586828701611101565b9497909650939450505050565b803580151581146111b257600080fd5b919050565b6000806000606084860312156111cc57600080fd5b83356111d781611049565b925060208401356111e781611049565b91506111f5604085016111a2565b90509250925092565b6000806040838503121561121157600080fd5b823561121c81611049565b915061122a602084016111a2565b90509250929050565b6000806020838503121561124657600080fd5b823567ffffffffffffffff81111561125d57600080fd5b61126985828601611101565b90969095509350505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b601f8201601f1916810167ffffffffffffffff811182821017156112c7576112c761128b565b6040525050565b600060208083850312156112e157600080fd5b825167ffffffffffffffff808211156112f957600080fd5b818501915085601f83011261130d57600080fd5b81518181111561131f5761131f61128b565b8060051b9150604051611334858401826112a1565b8181529183018401918481018884111561134d57600080fd5b938501935b83851015611375578451925061136783611049565b828152938501938501611352565b50979650505050505050565b600060033d111561139a5760046000803e5060005160e01c5b90565b600060443d10156113ab5790565b6040516003193d81016004833e81513d67ffffffffffffffff81602484011181841117156113db57505050505090565b82850191508151818111156113f35750505050505090565b843d870101602082850101111561140d5750505050505090565b61141c602082860101876112a1565b509095945050505050565b60006020808352835180602085015260005b8181101561145557858101830151858201604001528201611439565b506000604082860101526040601f19601f8301168501019250505092915050565b8181038181111561027157634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fdfea26469706673582212201da943aaab3d662638e90702afbb35c25529ff02eb4156f150f30b9fd91f757464736f6c63430008170033
Verified Source Code Full Match
Compiler: v0.8.23+commit.f704f362
EVM: paris
Optimization: Yes (1000 runs)
Ownable.sol 100 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
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;
}
}
EnumerableSet.sol 378 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.20;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(bytes32 value => uint256) _positions;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}
IClaimVault.sol 16 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;
/**
* @title Claim Vault Interface
* @author A Q T I S / @AQTIS-Team
* @notice Interface for claim vault
*/
interface IClaimVault {
function claimRewards(address lst) external;
function claimRewardsFor(address lst, address user) external;
function getLSTs() external view returns (address[] memory);
}
BatchClaimV2.sol 157 lines
// SPDX-License-Identifier: MIT
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";
/**
* @title BatchClaimV2 Contract
* @author A Q T I S
* @notice This contract handles batch claiming of rewards
*/
contract BatchClaimV2 is Ownable {
using EnumerableSet for EnumerableSet.AddressSet;
EnumerableSet.AddressSet internal _enabledUsers;
mapping(address => mapping(address => bool)) public userLSTConfig;
// dependencies
IClaimVault public claimVault;
address public scheduler;
// ======= Events ======= //
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);
}
// ======= Modifiers ======= //
modifier onlyScheduler() {
require(msg.sender == owner() || msg.sender == scheduler, "BatchClaim: Caller is not authorized");
_;
}
// ======= External Functions ======= //
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();
}
// ======= Permissioned Functions ======= //
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]);
}
}
}
// ======= Owner Functions ======= //
function setAutoClaimForUser(address user, address lst, bool _enabled) external onlyOwner {
_setAutoClaim(user, lst, _enabled);
}
// ======= Internal Functions ======= //
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) {
// Add user to enabled users if necessary
if (!_enabledUsers.contains(user)) {
_enabledUsers.add(user);
}
emit AutoClaimEnabled(user, lst);
} else {
// Remove user from enabled users if necessary
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) {
// success
} catch Error(string memory reason) {
emit ClaimFailed(user, lst, reason);
} catch {
emit ClaimFailed(user, lst, "Unknown error");
}
}
}
Read Contract
claimVault 0xab518e6e → address
getAutoClaimUsers 0x10078eb3 → address[]
isAutoClaimEnabled 0x07a38851 → bool
owner 0x8da5cb5b → address
scheduler 0xd1ad17bf → address
userLSTConfig 0xa0960281 → bool
Write Contract 9 functions
These functions modify contract state and require a wallet transaction to execute.
batchClaim 0xf4af0bd0
No parameters
multiClaim 0xc74cd014
address[] _users
multiClaimLST 0x610374a5
address lst
address[] _users
renounceOwnership 0x715018a6
No parameters
setAutoClaim 0x8bc1d639
address lst
bool _enabled
setAutoClaimForUser 0x85524efc
address user
address lst
bool _enabled
setScheduler 0x3f6746ce
address _scheduler
transferOwnership 0xf2fde38b
address newOwner
updateClaimVault 0x40a0b4ec
address _newClaimVault
Recent Transactions
No transactions found for this address