Source Code
Overview
HYPE Balance
HYPE Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ValidatorManager
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.20;
import {AccessControlEnumerableUpgradeable} from
"@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {IValidatorManager} from "./interfaces/IValidatorManager.sol";
import {IPauserRegistry} from "./interfaces/IPauserRegistry.sol";
import {IStakingManager} from "./interfaces/IStakingManager.sol";
/**
* @title ValidatorManager
* @notice Manages validator registration, performance tracking, and rebalancing
* @dev This contract handles validator lifecycle and stake rebalancing
*/
contract ValidatorManager is
IValidatorManager,
Initializable,
AccessControlEnumerableUpgradeable,
ReentrancyGuardUpgradeable
{
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
/* ========== LIBRARIES ========== */
using EnumerableSet for EnumerableSet.AddressSet;
using EnumerableMap for EnumerableMap.UintToAddressMap;
using EnumerableMap for EnumerableMap.AddressToUintMap;
/* ========== CONSTANTS ========== */
/// @notice Basis points denominator (100%)
uint256 public constant BASIS_POINTS = 10000;
/* ========== ROLES ========== */
/// @notice Role that can manage validators and operational parameters
bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
/// @notice Role that can update validator performance
bytes32 public constant ORACLE_MANAGER_ROLE = keccak256("ORACLE_MANAGER_ROLE");
/* ========== STATE VARIABLES ========== */
/// @notice Registry for pausing functionality
IPauserRegistry public pauserRegistry;
/// @notice Total amount slashed across all validators
uint256 public totalSlashing; // In 18 decimals
/// @notice Total rewards across all validators
uint256 public totalRewards; // In 18 decimals
/// @notice Mapping of staking manager to delegation target
mapping(address => address) public delegations;
/// @notice Mapping of validator to rebalance request
mapping(address => RebalanceRequest) public validatorRebalanceRequests;
/// @notice Mapping of validator to performance report
mapping(address => PerformanceReport) public validatorPerformance;
/// @notice Mapping of validator to total slashing amount
mapping(address => uint256) public validatorSlashing;
/// @notice Mapping of validator to total rewards
mapping(address => uint256) public validatorRewards;
/// @dev Array of all validators
Validator[] internal _validators;
/// @dev Mapping of validator address to index in _validators array
EnumerableMap.AddressToUintMap internal _validatorIndexes;
/// @dev Set of validators with pending rebalance
EnumerableSet.AddressSet internal _validatorsWithPendingRebalance;
/* ========== MODIFIERS ========== */
modifier whenNotPaused() {
require(!pauserRegistry.isPaused(address(this)), "Contract is paused");
_;
}
modifier validatorExists(address validator) {
require(_validatorIndexes.contains(validator), "Validator does not exist");
_;
}
modifier validatorActive(address validator) {
require(validatorActiveState(validator), "Validator not active");
_;
}
/* ========== INITIALIZATION ========== */
/**
* @notice Initialize the contract with initial configuration
* @param admin Address that will have admin role
* @param manager Address that will have manager role
* @param _oracle Address that will have oracle role
* @param _pauserRegistry Address of the pauser registry contract
*/
function initialize(address admin, address manager, address _oracle, address _pauserRegistry)
external
initializer
{
require(admin != address(0), "Invalid admin address");
require(manager != address(0), "Invalid manager address");
require(_oracle != address(0), "Invalid oracle address");
require(_pauserRegistry != address(0), "Invalid pauser registry");
__AccessControlEnumerable_init();
__ReentrancyGuard_init();
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(MANAGER_ROLE, manager);
_grantRole(ORACLE_MANAGER_ROLE, _oracle);
pauserRegistry = IPauserRegistry(_pauserRegistry);
}
/* ========== VALIDATOR MANAGEMENT ========== */
/**
* @notice Activate a new validator in the system
* @param validator Address of the validator to activate
*/
function activateValidator(address validator) external whenNotPaused onlyRole(MANAGER_ROLE) {
require(validator != address(0), "Invalid validator address");
require(!_validatorIndexes.contains(validator), "Validator already exists");
Validator memory newValidator =
Validator({balance: 0, performanceScore: 0, lastUpdateTime: block.timestamp, active: true});
_validators.push(newValidator);
_validatorIndexes.set(validator, _validators.length - 1);
emit ValidatorActivated(validator);
}
/**
* @notice Deactivate a validator
* @param validator Address of the validator to deactivate
*/
function deactivateValidator(address validator) external whenNotPaused nonReentrant validatorExists(validator) {
// limit the msg.sender to MANAGER_ROLE
require(hasRole(MANAGER_ROLE, msg.sender), "Not authorized");
(bool exists, uint256 index) = _validatorIndexes.tryGet(validator);
require(exists, "Validator does not exist");
Validator storage validatorData = _validators[index];
require(validatorData.active, "Validator already inactive");
// Update state after withdrawal request
validatorData.active = false;
emit ValidatorDeactivated(validator);
}
/**
* @notice Reactivate a previously deactivated validator
* @param validator Address of the validator to reactivate
*/
function reactivateValidator(address validator)
external
whenNotPaused
nonReentrant
onlyRole(MANAGER_ROLE)
validatorExists(validator)
{
(bool exists, uint256 index) = _validatorIndexes.tryGet(validator);
require(exists, "Validator does not exist");
Validator storage validatorData = _validators[index];
require(!validatorData.active, "Validator already active");
require(!_validatorsWithPendingRebalance.contains(validator), "Validator has pending rebalance");
// Reactivate the validator
validatorData.active = true;
emit ValidatorReactivated(validator);
}
/* ========== REBALANCING ========== */
/**
* @notice Request withdrawals for multiple validators
* @param stakingManager Address of the staking manager contract
* @param validators Array of validator addresses
* @param withdrawalAmounts Array of amounts to withdraw
*/
function rebalanceWithdrawal(
address stakingManager,
address[] calldata validators,
uint256[] calldata withdrawalAmounts
) external whenNotPaused nonReentrant onlyRole(MANAGER_ROLE) {
require(validators.length == withdrawalAmounts.length, "Length mismatch");
require(validators.length > 0, "Empty arrays");
for (uint256 i = 0; i < validators.length;) {
require(validators[i] != address(0), "Invalid validator address");
// Add rebalance request (this will check for duplicates)
_addRebalanceRequest(stakingManager, validators[i], withdrawalAmounts[i]);
unchecked {
++i;
}
}
// Trigger withdrawals through StakingManager
IStakingManager(stakingManager).processValidatorWithdrawals(validators, withdrawalAmounts);
}
/**
* @dev Internal function to add a rebalance request
* @param validator Address of the validator
* @param withdrawalAmount Amount to withdraw
*/
function _addRebalanceRequest(address staking, address validator, uint256 withdrawalAmount) internal {
require(!_validatorsWithPendingRebalance.contains(validator), "Validator has pending rebalance");
require(withdrawalAmount > 0, "Invalid withdrawal amount");
(bool exists, /* uint256 index */ ) = _validatorIndexes.tryGet(validator);
require(exists, "Validator does not exist");
validatorRebalanceRequests[validator] =
RebalanceRequest({staking: staking, validator: validator, amount: withdrawalAmount});
_validatorsWithPendingRebalance.add(validator);
emit RebalanceRequestAdded(validator, withdrawalAmount);
}
/**
* @notice Close multiple rebalance requests and redelegate
* @param stakingManager Address of the staking manager contract
* @param validators Array of validator addresses
* @dev Clears the rebalance requests and triggers redelegation through stakingManager
*/
function closeRebalanceRequests(address stakingManager, address[] calldata validators)
external
whenNotPaused
nonReentrant
onlyRole(MANAGER_ROLE)
{
require(_validatorsWithPendingRebalance.length() > 0, "No pending requests");
require(validators.length > 0, "Empty array");
uint256 totalAmount = 0;
for (uint256 i = 0; i < validators.length;) {
address validator = validators[i];
require(_validatorsWithPendingRebalance.contains(validator), "No pending request");
// Add amount to total for redelegation
RebalanceRequest memory request = validatorRebalanceRequests[validator];
require(request.staking == stakingManager, "Invalid staking manager for rebalance");
totalAmount += request.amount;
// Clear the rebalance request
delete validatorRebalanceRequests[validator];
_validatorsWithPendingRebalance.remove(validator);
emit RebalanceRequestClosed(validator, request.amount);
unchecked {
++i;
}
}
// Trigger redelegation through StakingManager if there's an amount to delegate
if (totalAmount > 0) {
IStakingManager(stakingManager).processValidatorRedelegation(totalAmount);
}
}
/**
* @notice Check if a validator has a pending rebalance request
* @param validator Address of the validator to check
* @return bool True if the validator has a pending rebalance request
*/
function hasPendingRebalance(address validator) external view returns (bool) {
return _validatorsWithPendingRebalance.contains(validator);
}
/* ========== PERFORMANCE MONITORING ========== */
/// @notice Updates performance scores for a validator
/// @param validator Address of validator
/// @param balance Current balance of the validator
/// @param performanceScore New performance score (0-10000)
function updateValidatorPerformance(address validator, uint256 balance, uint256 performanceScore)
external
whenNotPaused
onlyRole(ORACLE_MANAGER_ROLE)
validatorActive(validator)
{
// Much simpler validation
require(performanceScore <= BASIS_POINTS, "Score exceeds maximum");
uint256 index = _validatorIndexes.get(validator);
// Update validator struct
_validators[index].balance = balance;
_validators[index].performanceScore = performanceScore;
_validators[index].lastUpdateTime = block.timestamp;
// Update performance report in one storage write
validatorPerformance[validator] =
PerformanceReport({balance: balance, performanceScore: performanceScore, timestamp: block.timestamp});
emit ValidatorPerformanceUpdated(validator, block.timestamp, block.number);
}
/* ========== PERFORMANCE QUERIES ========== */
function validatorScores(address validator)
external
view
validatorExists(validator)
returns (uint256 performanceScore)
{
Validator memory val = _validators[_validatorIndexes.get(validator)];
return val.performanceScore;
}
function validatorLastUpdateTime(address validator) external view validatorExists(validator) returns (uint256) {
return _validators[_validatorIndexes.get(validator)].lastUpdateTime;
}
function validatorBalance(address validator) external view validatorExists(validator) returns (uint256) {
return _validators[_validatorIndexes.get(validator)].balance;
}
function validatorActiveState(address validator) public view validatorExists(validator) returns (bool) {
return _validators[_validatorIndexes.get(validator)].active;
}
function activeValidatorsCount() external view returns (uint256) {
uint256 count;
uint256 length = _validators.length;
for (uint256 i; i < length;) {
if (_validators[i].active) {
count++;
}
unchecked {
++i;
}
}
return count;
}
function validatorCount() public view returns (uint256) {
return _validators.length;
}
function validatorAt(uint256 index) public view returns (address validator, Validator memory data) {
uint256 length = _validators.length;
require(index < length, "Index out of bounds");
(validator,) = _validatorIndexes.at(index);
data = _validators[index];
return (validator, data);
}
function validatorInfo(address validator) public view validatorExists(validator) returns (Validator memory) {
return _validators[_validatorIndexes.get(validator)];
}
/* ========== REWARDS ========== */
/// @notice Report a reward event for a validator
/// @param validator Address of the validator to be rewarded
/// @param amount Amount of rewards for the validator
function reportRewardEvent(address validator, uint256 amount)
external
onlyRole(ORACLE_MANAGER_ROLE)
validatorActive(validator)
{
require(amount > 0, "Invalid reward amount");
// Update reward amounts
totalRewards += amount;
validatorRewards[validator] += amount;
emit RewardEventReported(validator, amount);
}
/* ========== SLASHING ========== */
/// @notice Report a slashing event for a validator
/// @param validator Address of the validator to be slashed
/// @param amount Amount to slash from the validator
function reportSlashingEvent(address validator, uint256 amount)
external
onlyRole(ORACLE_MANAGER_ROLE)
validatorActive(validator)
{
require(amount > 0, "Invalid slash amount");
// Update slashing amounts
totalSlashing += amount;
validatorSlashing[validator] += amount;
emit SlashingEventReported(validator, amount);
}
/* ========== DELEGATION MANAGEMENT ========== */
/**
* @notice Set delegation target for a staking manager
* @param stakingManager Address of the staking manager
* @param validator Address of the validator to delegate to
*/
function setDelegation(address stakingManager, address validator)
external
whenNotPaused
onlyRole(MANAGER_ROLE)
validatorActive(validator)
{
require(stakingManager != address(0), "Invalid staking manager");
address oldDelegation = delegations[stakingManager];
delegations[stakingManager] = validator;
emit DelegationUpdated(stakingManager, oldDelegation, validator);
}
/**
* @notice Get delegation target for a staking manager
* @param stakingManager Address of the staking manager
* @return Address of the validator to delegate to
*/
function getDelegation(address stakingManager) external view returns (address) {
address validator = delegations[stakingManager];
require(validator != address(0), "No delegation set");
require(validatorActiveState(validator), "Delegated validator not active");
return validator;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/extensions/AccessControlEnumerable.sol)
pragma solidity ^0.8.20;
import {IAccessControlEnumerable} from "@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol";
import {AccessControlUpgradeable} from "../AccessControlUpgradeable.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Extension of {AccessControl} that allows enumerating the members of each role.
*/
abstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerable, AccessControlUpgradeable {
using EnumerableSet for EnumerableSet.AddressSet;
/// @custom:storage-location erc7201:openzeppelin.storage.AccessControlEnumerable
struct AccessControlEnumerableStorage {
mapping(bytes32 role => EnumerableSet.AddressSet) _roleMembers;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessControlEnumerable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant AccessControlEnumerableStorageLocation = 0xc1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e82371705932000;
function _getAccessControlEnumerableStorage() private pure returns (AccessControlEnumerableStorage storage $) {
assembly {
$.slot := AccessControlEnumerableStorageLocation
}
}
function __AccessControlEnumerable_init() internal onlyInitializing {
}
function __AccessControlEnumerable_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) public view virtual returns (address) {
AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();
return $._roleMembers[role].at(index);
}
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) public view virtual returns (uint256) {
AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();
return $._roleMembers[role].length();
}
/**
* @dev Return all accounts that have `role`
*
* 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 getRoleMembers(bytes32 role) public view virtual returns (address[] memory) {
AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();
return $._roleMembers[role].values();
}
/**
* @dev Overload {AccessControl-_grantRole} to track enumerable memberships
*/
function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {
AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();
bool granted = super._grantRole(role, account);
if (granted) {
$._roleMembers[role].add(account);
}
return granted;
}
/**
* @dev Overload {AccessControl-_revokeRole} to track enumerable memberships
*/
function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {
AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();
bool revoked = super._revokeRole(role, account);
if (revoked) {
$._roleMembers[role].remove(account);
}
return revoked;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuardUpgradeable is Initializable {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
/// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard
struct ReentrancyGuardStorage {
uint256 _status;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.ReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;
function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {
assembly {
$.slot := ReentrancyGuardStorageLocation
}
}
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
function __ReentrancyGuard_init() internal onlyInitializing {
__ReentrancyGuard_init_unchained();
}
function __ReentrancyGuard_init_unchained() internal onlyInitializing {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
$._status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
// On the first call to nonReentrant, _status will be NOT_ENTERED
if ($._status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
$._status = ENTERED;
}
function _nonReentrantAfter() private {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
$._status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();
return $._status == ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/structs/EnumerableMap.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.
pragma solidity ^0.8.20;
import {EnumerableSet} from "./EnumerableSet.sol";
/**
* @dev Library for managing an enumerable variant of Solidity's
* https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
* type.
*
* Maps have the following properties:
*
* - Entries are added, removed, and checked for existence in constant time
* (O(1)).
* - Entries are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableMap for EnumerableMap.UintToAddressMap;
*
* // Declare a set state variable
* EnumerableMap.UintToAddressMap private myMap;
* }
* ```
*
* The following map types are supported:
*
* - `uint256 -> address` (`UintToAddressMap`) since v3.0.0
* - `address -> uint256` (`AddressToUintMap`) since v4.6.0
* - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0
* - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0
* - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0
* - `uint256 -> bytes32` (`UintToBytes32Map`) since v5.1.0
* - `address -> address` (`AddressToAddressMap`) since v5.1.0
* - `address -> bytes32` (`AddressToBytes32Map`) since v5.1.0
* - `bytes32 -> address` (`Bytes32ToAddressMap`) since v5.1.0
*
* [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 EnumerableMap, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableMap.
* ====
*/
library EnumerableMap {
using EnumerableSet for EnumerableSet.Bytes32Set;
// To implement this library for multiple types with as little code repetition as possible, we write it in
// terms of a generic Map type with bytes32 keys and values. The Map implementation uses private functions,
// and user-facing implementations such as `UintToAddressMap` are just wrappers around the underlying Map.
// This means that we can only create new EnumerableMaps for types that fit in bytes32.
/**
* @dev Query for a nonexistent map key.
*/
error EnumerableMapNonexistentKey(bytes32 key);
struct Bytes32ToBytes32Map {
// Storage of keys
EnumerableSet.Bytes32Set _keys;
mapping(bytes32 key => bytes32) _values;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) {
map._values[key] = value;
return map._keys.add(key);
}
/**
* @dev Removes a key-value pair from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {
delete map._values[key];
return map._keys.remove(key);
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {
return map._keys.contains(key);
}
/**
* @dev Returns the number of key-value pairs in the map. O(1).
*/
function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {
return map._keys.length();
}
/**
* @dev Returns the key-value pair stored at position `index` in the map. O(1).
*
* Note that there are no guarantees on the ordering of entries inside the
* array, and it may change when more entries are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32 key, bytes32 value) {
bytes32 atKey = map._keys.at(index);
return (atKey, map._values[atKey]);
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool exists, bytes32 value) {
bytes32 val = map._values[key];
if (val == bytes32(0)) {
return (contains(map, key), bytes32(0));
} else {
return (true, val);
}
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {
bytes32 value = map._values[key];
if (value == 0 && !contains(map, key)) {
revert EnumerableMapNonexistentKey(key);
}
return value;
}
/**
* @dev Return the an array containing all the keys
*
* 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 map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) {
return map._keys.values();
}
// UintToUintMap
struct UintToUintMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) {
return set(map._inner, bytes32(key), bytes32(value));
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {
return remove(map._inner, bytes32(key));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {
return contains(map._inner, bytes32(key));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(UintToUintMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. 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(UintToUintMap storage map, uint256 index) internal view returns (uint256 key, uint256 value) {
(bytes32 atKey, bytes32 val) = at(map._inner, index);
return (uint256(atKey), uint256(val));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool exists, uint256 value) {
(bool success, bytes32 val) = tryGet(map._inner, bytes32(key));
return (success, uint256(val));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {
return uint256(get(map._inner, bytes32(key)));
}
/**
* @dev Return the an array containing all the keys
*
* 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 map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(UintToUintMap storage map) internal view returns (uint256[] memory) {
bytes32[] memory store = keys(map._inner);
uint256[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// UintToAddressMap
struct UintToAddressMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
return remove(map._inner, bytes32(key));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
return contains(map._inner, bytes32(key));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(UintToAddressMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. 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(UintToAddressMap storage map, uint256 index) internal view returns (uint256 key, address value) {
(bytes32 atKey, bytes32 val) = at(map._inner, index);
return (uint256(atKey), address(uint160(uint256(val))));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool exists, address value) {
(bool success, bytes32 val) = tryGet(map._inner, bytes32(key));
return (success, address(uint160(uint256(val))));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
return address(uint160(uint256(get(map._inner, bytes32(key)))));
}
/**
* @dev Return the an array containing all the keys
*
* 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 map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) {
bytes32[] memory store = keys(map._inner);
uint256[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// UintToBytes32Map
struct UintToBytes32Map {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(UintToBytes32Map storage map, uint256 key, bytes32 value) internal returns (bool) {
return set(map._inner, bytes32(key), value);
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(UintToBytes32Map storage map, uint256 key) internal returns (bool) {
return remove(map._inner, bytes32(key));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(UintToBytes32Map storage map, uint256 key) internal view returns (bool) {
return contains(map._inner, bytes32(key));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(UintToBytes32Map storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. 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(UintToBytes32Map storage map, uint256 index) internal view returns (uint256 key, bytes32 value) {
(bytes32 atKey, bytes32 val) = at(map._inner, index);
return (uint256(atKey), val);
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(UintToBytes32Map storage map, uint256 key) internal view returns (bool exists, bytes32 value) {
(bool success, bytes32 val) = tryGet(map._inner, bytes32(key));
return (success, val);
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(UintToBytes32Map storage map, uint256 key) internal view returns (bytes32) {
return get(map._inner, bytes32(key));
}
/**
* @dev Return the an array containing all the keys
*
* 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 map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(UintToBytes32Map storage map) internal view returns (uint256[] memory) {
bytes32[] memory store = keys(map._inner);
uint256[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// AddressToUintMap
struct AddressToUintMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) {
return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(AddressToUintMap storage map, address key) internal returns (bool) {
return remove(map._inner, bytes32(uint256(uint160(key))));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(AddressToUintMap storage map, address key) internal view returns (bool) {
return contains(map._inner, bytes32(uint256(uint160(key))));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(AddressToUintMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. 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(AddressToUintMap storage map, uint256 index) internal view returns (address key, uint256 value) {
(bytes32 atKey, bytes32 val) = at(map._inner, index);
return (address(uint160(uint256(atKey))), uint256(val));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(AddressToUintMap storage map, address key) internal view returns (bool exists, uint256 value) {
(bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key))));
return (success, uint256(val));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(AddressToUintMap storage map, address key) internal view returns (uint256) {
return uint256(get(map._inner, bytes32(uint256(uint160(key)))));
}
/**
* @dev Return the an array containing all the keys
*
* 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 map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(AddressToUintMap storage map) internal view returns (address[] memory) {
bytes32[] memory store = keys(map._inner);
address[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// AddressToAddressMap
struct AddressToAddressMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(AddressToAddressMap storage map, address key, address value) internal returns (bool) {
return set(map._inner, bytes32(uint256(uint160(key))), bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(AddressToAddressMap storage map, address key) internal returns (bool) {
return remove(map._inner, bytes32(uint256(uint160(key))));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(AddressToAddressMap storage map, address key) internal view returns (bool) {
return contains(map._inner, bytes32(uint256(uint160(key))));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(AddressToAddressMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. 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(AddressToAddressMap storage map, uint256 index) internal view returns (address key, address value) {
(bytes32 atKey, bytes32 val) = at(map._inner, index);
return (address(uint160(uint256(atKey))), address(uint160(uint256(val))));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(AddressToAddressMap storage map, address key) internal view returns (bool exists, address value) {
(bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key))));
return (success, address(uint160(uint256(val))));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(AddressToAddressMap storage map, address key) internal view returns (address) {
return address(uint160(uint256(get(map._inner, bytes32(uint256(uint160(key)))))));
}
/**
* @dev Return the an array containing all the keys
*
* 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 map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(AddressToAddressMap storage map) internal view returns (address[] memory) {
bytes32[] memory store = keys(map._inner);
address[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// AddressToBytes32Map
struct AddressToBytes32Map {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(AddressToBytes32Map storage map, address key, bytes32 value) internal returns (bool) {
return set(map._inner, bytes32(uint256(uint160(key))), value);
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(AddressToBytes32Map storage map, address key) internal returns (bool) {
return remove(map._inner, bytes32(uint256(uint160(key))));
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(AddressToBytes32Map storage map, address key) internal view returns (bool) {
return contains(map._inner, bytes32(uint256(uint160(key))));
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(AddressToBytes32Map storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. 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(AddressToBytes32Map storage map, uint256 index) internal view returns (address key, bytes32 value) {
(bytes32 atKey, bytes32 val) = at(map._inner, index);
return (address(uint160(uint256(atKey))), val);
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(AddressToBytes32Map storage map, address key) internal view returns (bool exists, bytes32 value) {
(bool success, bytes32 val) = tryGet(map._inner, bytes32(uint256(uint160(key))));
return (success, val);
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(AddressToBytes32Map storage map, address key) internal view returns (bytes32) {
return get(map._inner, bytes32(uint256(uint160(key))));
}
/**
* @dev Return the an array containing all the keys
*
* 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 map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(AddressToBytes32Map storage map) internal view returns (address[] memory) {
bytes32[] memory store = keys(map._inner);
address[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// Bytes32ToUintMap
struct Bytes32ToUintMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) {
return set(map._inner, key, bytes32(value));
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {
return remove(map._inner, key);
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {
return contains(map._inner, key);
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(Bytes32ToUintMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. 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(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32 key, uint256 value) {
(bytes32 atKey, bytes32 val) = at(map._inner, index);
return (atKey, uint256(val));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool exists, uint256 value) {
(bool success, bytes32 val) = tryGet(map._inner, key);
return (success, uint256(val));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {
return uint256(get(map._inner, key));
}
/**
* @dev Return the an array containing all the keys
*
* 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 map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) {
bytes32[] memory store = keys(map._inner);
bytes32[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// Bytes32ToAddressMap
struct Bytes32ToAddressMap {
Bytes32ToBytes32Map _inner;
}
/**
* @dev Adds a key-value pair to a map, or updates the value for an existing
* key. O(1).
*
* Returns true if the key was added to the map, that is if it was not
* already present.
*/
function set(Bytes32ToAddressMap storage map, bytes32 key, address value) internal returns (bool) {
return set(map._inner, key, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a map. O(1).
*
* Returns true if the key was removed from the map, that is if it was present.
*/
function remove(Bytes32ToAddressMap storage map, bytes32 key) internal returns (bool) {
return remove(map._inner, key);
}
/**
* @dev Returns true if the key is in the map. O(1).
*/
function contains(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool) {
return contains(map._inner, key);
}
/**
* @dev Returns the number of elements in the map. O(1).
*/
function length(Bytes32ToAddressMap storage map) internal view returns (uint256) {
return length(map._inner);
}
/**
* @dev Returns the element stored at position `index` in the map. 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(Bytes32ToAddressMap storage map, uint256 index) internal view returns (bytes32 key, address value) {
(bytes32 atKey, bytes32 val) = at(map._inner, index);
return (atKey, address(uint160(uint256(val))));
}
/**
* @dev Tries to returns the value associated with `key`. O(1).
* Does not revert if `key` is not in the map.
*/
function tryGet(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (bool exists, address value) {
(bool success, bytes32 val) = tryGet(map._inner, key);
return (success, address(uint160(uint256(val))));
}
/**
* @dev Returns the value associated with `key`. O(1).
*
* Requirements:
*
* - `key` must be in the map.
*/
function get(Bytes32ToAddressMap storage map, bytes32 key) internal view returns (address) {
return address(uint160(uint256(get(map._inner, key))));
}
/**
* @dev Return the an array containing all the keys
*
* 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 map grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function keys(Bytes32ToAddressMap storage map) internal view returns (bytes32[] memory) {
bytes32[] memory store = keys(map._inner);
bytes32[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.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;
assembly ("memory-safe") {
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;
assembly ("memory-safe") {
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;
assembly ("memory-safe") {
result := store
}
return result;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title IValidatorManager
* @notice Interface for the ValidatorManager contract that manages validator operations
*/
interface IValidatorManager {
/* ========== STRUCTS ========== */
/// @notice Struct containing validator information and performance metrics
struct Validator {
uint256 balance; // Current balance/stake of the validator
uint256 performanceScore; // Single aggregated performance score (0-10000)
uint256 lastUpdateTime; // Timestamp of last score update
bool active; // Whether the validator is currently active
}
struct RebalanceRequest {
address staking; // Staking that initiated the request's belonging
address validator; // Validator being rebalanced
uint256 amount; // Amount to move
}
struct PerformanceReport {
uint256 balance;
uint256 performanceScore; // Single aggregated performance score
uint256 timestamp;
}
/* ========== EVENTS ========== */
event EmergencyWithdrawalLimitUpdated(uint256 newLimit);
event ValidatorAdded(address indexed validator);
event ValidatorRemoved(address indexed validator);
event ValidatorScoreUpdated(address indexed validator, uint256 performanceScore);
event StakeRebalanced(address indexed validator, uint256 newStake);
event StakeLimitsUpdated(uint256 minLimit, uint256 maxLimit);
event EmergencyWithdrawalRequested(address indexed validator, uint256 amount);
event EmergencyWithdrawalProcessed(address indexed validator, uint256 amount);
event SlashingEventReported(address indexed validator, uint256 amount);
event PerformanceReportGenerated(address indexed validator, uint256 timestamp);
event RebalanceRequestAdded(address indexed validator, uint256 amount);
event RebalanceBatchProcessed(uint256 startIndex, uint256 endIndex, uint256 timestamp);
event RebalanceRequestClosed(address indexed validator, uint256 amount);
event AllRebalanceRequestsClosed(uint256 count, uint256 timestamp);
event EmergencyCooldownUpdated(uint256 cooldown);
event RebalanceCooldownUpdated(uint256 cooldown);
event ValidatorActivated(address indexed validator);
event ValidatorDeactivated(address indexed validator);
event ValidatorReactivated(address indexed validator);
event ValidatorPerformanceUpdated(address indexed validator, uint256 timestamp, uint256 blockNumber);
event RewardEventReported(address indexed validator, uint256 amount);
event DelegationUpdated(
address indexed stakingManager, address indexed oldDelegation, address indexed newDelegation
);
/* ========== VIEW FUNCTIONS ========== */
/// @notice Gets the total number of validators
function validatorCount() external view returns (uint256);
/// @notice Gets validator info at a specific index
function validatorAt(uint256 index) external view returns (address, Validator memory);
/// @notice Gets validator info for a specific address
function validatorInfo(address validator) external view returns (Validator memory);
/// @notice Gets validator performance score
function validatorScores(address validator) external view returns (uint256 performanceScore);
/// @notice Gets validator balance
function validatorBalance(address validator) external view returns (uint256);
/// @notice Gets validator active state
function validatorActiveState(address validator) external view returns (bool);
/// @notice Gets total slashing amount
function totalSlashing() external view returns (uint256);
/// @notice Get validator's last update time
function validatorLastUpdateTime(address validator) external view returns (uint256);
/// @notice Check if validator has pending rebalance
function hasPendingRebalance(address validator) external view returns (bool);
/// @notice Get total rewards across all validators
function totalRewards() external view returns (uint256);
/// @notice Get the total rewards earned by a validator
function validatorRewards(address validator) external view returns (uint256);
/// @notice Get the total amount slashed from a validator
function validatorSlashing(address validator) external view returns (uint256);
/// @notice Get the delegation address for the staking
function getDelegation(address stakingManager) external view returns (address);
/* ========== MUTATIVE FUNCTIONS ========== */
/// @notice Activates a validator
function activateValidator(address validator) external;
/// @notice Deactivates a validator
function deactivateValidator(address validator) external;
/// @notice Updates validator performance metrics with single aggregated score
function updateValidatorPerformance(address validator, uint256 balance, uint256 performanceScore) external;
/// @notice Reports a slashing event for a validator
function reportSlashingEvent(address validator, uint256 slashAmount) external;
/// @notice Report a reward event for a validator
function reportRewardEvent(address validator, uint256 amount) external;
/// @notice Request withdrawals for multiple validators
function rebalanceWithdrawal(
address stakingManager,
address[] calldata validators,
uint256[] calldata withdrawalAmounts
) external;
/// @notice Close multiple rebalance requests
function closeRebalanceRequests(address stakingManager, address[] calldata validators) external;
/// @notice Set the delegation address for the staking
function setDelegation(address stakingManager, address validator) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title IPauserRegistry
* @notice Interface for the PauserRegistry contract that manages protocol pause states
*/
interface IPauserRegistry {
/* ========== EVENTS ========== */
event ContractPaused(address indexed contractAddress);
event ContractUnpaused(address indexed contractAddress);
event ContractAuthorized(address indexed contractAddress);
event ContractDeauthorized(address indexed contractAddress);
/* ========== VIEW FUNCTIONS ========== */
/**
* @notice Checks if a contract is paused
* @param contractAddress The address of the contract to check
* @return bool True if the contract is paused
*/
function isPaused(address contractAddress) external view returns (bool);
/**
* @notice Checks if a contract is authorized
* @param contractAddress The address of the contract to check
* @return bool True if the contract is authorized
*/
function isAuthorizedContract(address contractAddress) external view returns (bool);
/**
* @notice Gets all authorized contracts
* @return address[] Array of authorized contract addresses
*/
function getAuthorizedContracts() external view returns (address[] memory);
/**
* @notice Gets the count of authorized contracts
* @return uint256 Number of authorized contracts
*/
function getAuthorizedContractCount() external view returns (uint256);
/* ========== MUTATIVE FUNCTIONS ========== */
/**
* @notice Pauses a specific contract
* @param contractAddress The address of the contract to pause
*/
function pauseContract(address contractAddress) external;
/**
* @notice Unpauses a specific contract
* @param contractAddress The address of the contract to unpause
*/
function unpauseContract(address contractAddress) external;
/**
* @notice Pauses all authorized contracts
*/
function emergencyPauseAll() external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IStakingManager {
/* ========== STRUCTS ========== */
struct WithdrawalRequest {
uint256 hypeAmount; // Amount in HYPE to withdraw
uint256 kHYPEAmount; // Amount in kHYPE to burn (excluding fee)
uint256 kHYPEFee; // Fee amount in kHYPE tokens
uint256 bufferUsed; // Amount fulfilled from hypeBuffer
uint256 timestamp; // Request timestamp
}
// Define the enum on operation type
enum OperationType {
UserDeposit, // 0: User deposit operation; from EVM to Validator
SpotDeposit, // 1: Deposit operation from SpotAccount to Validator(handling dusts)
RebalanceDeposit, // 2: Rebalancing deposit operation; from StakingAccount to Validator
UserWithdrawal, // 3: User withdrawal; From Validator to EVM
RebalanceWithdrawal // 4: Rebalancing withdrawal; From Validator to StakingAccount
}
// Update the L1Operation struct to use the enum
struct L1Operation {
address validator;
uint256 amount;
OperationType operationType;
}
/* ========== EVENTS ========== */
event StakeReceived(address indexed staking, address indexed staker, uint256 amount);
event WithdrawalQueued(
address indexed staking,
address indexed user,
uint256 indexed withdrawalId,
uint256 kHYPEAmount,
uint256 hypeAmount,
uint256 feeAmount
);
event WithdrawalConfirmed(address indexed user, uint256 indexed withdrawalId, uint256 amount);
event WithdrawalCancelled(
address indexed user, uint256 indexed withdrawalId, uint256 amount, uint256 totalCancelled
);
event StakingLimitUpdated(uint256 newStakingLimit);
event MinStakeAmountUpdated(uint256 newMinStakeAmount);
event MaxStakeAmountUpdated(uint256 newMaxStakeAmount);
event MinWithdrawalAmountUpdated(uint256 newMinWithdrawalAmount);
event WithdrawalDelayUpdated(uint256 newDelay);
event Delegate(address indexed staking, address indexed validator, uint256 amount);
event TargetBufferUpdated(uint256 newTargetBuffer);
event BufferIncreased(uint256 amountAdded, uint256 newTotal);
event BufferDecreased(uint256 amountRemoved, uint256 newTotal);
event ValidatorWithdrawal(address indexed staking, address indexed validator, uint256 amount);
event WhitelistEnabled();
event WhitelistDisabled();
event AddressWhitelisted(address indexed account);
event AddressRemovedFromWhitelist(address indexed account);
// Add events for pause state changes
event StakingPaused(address indexed by);
event StakingUnpaused(address indexed by);
event WithdrawalPaused(address indexed by);
event WithdrawalUnpaused(address indexed by);
event WithdrawalRedelegated(uint256 amount);
event UnstakeFeeRateUpdated(uint256 newRate);
// Add event for treasury updates
event TreasuryUpdated(address indexed oldTreasury, address indexed newTreasury);
// Add event for stake & unstake queued L1 operations, amount is decimal 8 here
event L1DelegationQueued(
address indexed staking, address indexed validator, uint256 amount, OperationType operationType
);
event L1DelegationProcessed(
address indexed staking, address indexed validator, uint256 amount, OperationType operationType
);
event SpotWithdrawn(uint256 amount);
// Add events for airdrops
/**
* @notice Emitted when a token is withdrawn from spot balance
* @param tokenId The ID of the token withdrawn
* @param amount The amount withdrawn
* @param recipient The address receiving the tokens
*/
event TokenWithdrawnFromSpot(uint64 indexed tokenId, uint64 amount, address indexed recipient);
/**
* @notice Emitted when a token is rescued from the contract
* @param token The address of the token rescued (address(0) for native tokens)
* @param amount The amount rescued
* @param recipient The address receiving the tokens
*/
event TokenRescued(address indexed token, uint256 amount, address indexed recipient);
/**
* @notice Emitted when L1 operations are queued for retry
* @param validators Array of validator addresses
* @param amounts Array of amounts
* @param operationTypes Array of operation types
*/
event L1OperationsQueued(address[] validators, uint256[] amounts, OperationType[] operationTypes);
/**
* @notice Emitted when L1 operations are processed in batch
* @param processedCount Number of operations processed
* @param remainingCount Number of operations remaining
*/
event L1OperationsBatchProcessed(uint256 processedCount, uint256 remainingCount);
/**
* @notice Emitted when the L1 operations queue is reset
* @param queueLength Length of the queue before reset
*/
event L1OperationsQueueReset(uint256 queueLength);
/**
* @notice Emitted when an emergency withdrawal is executed
* @param validator Address of the validator
* @param amount Amount withdrawn
*/
event EmergencyWithdrawalExecuted(address indexed validator, uint256 amount);
/* ========== VIEW FUNCTIONS ========== */
/// @notice Gets the total amount of HYPE staked
function totalStaked() external view returns (uint256);
/// @notice Gets the total amount of HYPE claimed
function totalClaimed() external view returns (uint256);
/// @notice Gets the total amount of queued withdrawals
function totalQueuedWithdrawals() external view returns (uint256);
/// @notice Gets the current HYPE buffer amount
function hypeBuffer() external view returns (uint256);
/// @notice Gets the target buffer size
function targetBuffer() external view returns (uint256);
/// @notice Gets the maximum total staking limit
function stakingLimit() external view returns (uint256);
/// @notice Gets the minimum stake amount per transaction
function minStakeAmount() external view returns (uint256);
/// @notice Gets the maximum stake amount per transaction
function maxStakeAmount() external view returns (uint256);
/// @notice Gets the withdrawal delay period
function withdrawalDelay() external view returns (uint256);
/// @notice Gets withdrawal request details for a user
function withdrawalRequests(address user, uint256 id) external view returns (WithdrawalRequest memory);
/// @notice Gets the next withdrawal ID for a user
function nextWithdrawalId(address user) external view returns (uint256);
/// @notice Gets the current unstake fee rate
function unstakeFeeRate() external view returns (uint256);
/* ========== MUTATIVE FUNCTIONS ========== */
/// @notice Stakes HYPE tokens
function stake() external payable;
/// @notice Queues a withdrawal request
function queueWithdrawal(uint256 amount) external;
/// @notice Confirms a withdrawal request
function confirmWithdrawal(uint256 withdrawalId) external;
/**
* @notice Process validator withdrawals requested by ValidatorManager
* @param validators Array of validator addresses
* @param amounts Array of amounts to withdraw
*/
function processValidatorWithdrawals(address[] calldata validators, uint256[] calldata amounts) external;
/**
* @notice Delegate available balance to current validator
* @param amount Amount to delegate
*/
function processValidatorRedelegation(uint256 amount) external;
/**
* @notice Queue L1 operations directly for retrying failed operations
* @param validators Array of validator addresses
* @param amounts Array of amounts to process
* @param operationTypes Array of operation types
*/
function queueL1Operations(
address[] calldata validators,
uint256[] calldata amounts,
OperationType[] calldata operationTypes
) external;
/* ========== WHITELIST FUNCTIONS ========== */
function enableWhitelist() external;
function disableWhitelist() external;
function addToWhitelist(address[] calldata accounts) external;
function removeFromWhitelist(address[] calldata accounts) external;
function isWhitelisted(address account) external view returns (bool);
function whitelistLength() external view returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/extensions/IAccessControlEnumerable.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "../IAccessControl.sol";
/**
* @dev External interface of AccessControlEnumerable declared to support ERC-165 detection.
*/
interface IAccessControlEnumerable is IAccessControl {
/**
* @dev Returns one of the accounts that have `role`. `index` must be a
* value between 0 and {getRoleMemberCount}, non-inclusive.
*
* Role bearers are not sorted in any particular way, and their ordering may
* change at any point.
*
* WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
* you perform all queries on the same block. See the following
* https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
* for more information.
*/
function getRoleMember(bytes32 role, uint256 index) external view returns (address);
/**
* @dev Returns the number of accounts that have `role`. Can be used
* together with {getRoleMember} to enumerate all bearers of a role.
*/
function getRoleMemberCount(bytes32 role) external view returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "@openzeppelin/contracts/access/IAccessControl.sol";
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {ERC165Upgradeable} from "../utils/introspection/ERC165Upgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/// @custom:storage-location erc7201:openzeppelin.storage.AccessControl
struct AccessControlStorage {
mapping(bytes32 role => RoleData) _roles;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessControl")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant AccessControlStorageLocation = 0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800;
function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) {
assembly {
$.slot := AccessControlStorageLocation
}
}
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function __AccessControl_init() internal onlyInitializing {
}
function __AccessControl_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
AccessControlStorage storage $ = _getAccessControlStorage();
return $._roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
AccessControlStorage storage $ = _getAccessControlStorage();
return $._roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
AccessControlStorage storage $ = _getAccessControlStorage();
bytes32 previousAdminRole = getRoleAdmin(role);
$._roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
AccessControlStorage storage $ = _getAccessControlStorage();
if (!hasRole(role, account)) {
$._roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
AccessControlStorage storage $ = _getAccessControlStorage();
if (hasRole(role, account)) {
$._roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @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 ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
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;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165Upgradeable is Initializable, IERC165 {
function __ERC165_init() internal onlyInitializing {
}
function __ERC165_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": true,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"bytes32","name":"key","type":"bytes32"}],"name":"EnumerableMapNonexistentKey","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"AllRebalanceRequestsClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"stakingManager","type":"address"},{"indexed":true,"internalType":"address","name":"oldDelegation","type":"address"},{"indexed":true,"internalType":"address","name":"newDelegation","type":"address"}],"name":"DelegationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cooldown","type":"uint256"}],"name":"EmergencyCooldownUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newLimit","type":"uint256"}],"name":"EmergencyWithdrawalLimitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdrawalProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdrawalRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"PerformanceReportGenerated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"startIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"RebalanceBatchProcessed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"cooldown","type":"uint256"}],"name":"RebalanceCooldownUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RebalanceRequestAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RebalanceRequestClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardEventReported","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"SlashingEventReported","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxLimit","type":"uint256"}],"name":"StakeLimitsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"newStake","type":"uint256"}],"name":"StakeRebalanced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"}],"name":"ValidatorActivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"}],"name":"ValidatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"}],"name":"ValidatorDeactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"ValidatorPerformanceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"}],"name":"ValidatorReactivated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"}],"name":"ValidatorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"performanceScore","type":"uint256"}],"name":"ValidatorScoreUpdated","type":"event"},{"inputs":[],"name":"BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"activateValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"activeValidatorsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakingManager","type":"address"},{"internalType":"address[]","name":"validators","type":"address[]"}],"name":"closeRebalanceRequests","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"deactivateValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"delegations","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stakingManager","type":"address"}],"name":"getDelegation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMembers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"hasPendingRebalance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"manager","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_pauserRegistry","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pauserRegistry","outputs":[{"internalType":"contract IPauserRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"reactivateValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingManager","type":"address"},{"internalType":"address[]","name":"validators","type":"address[]"},{"internalType":"uint256[]","name":"withdrawalAmounts","type":"uint256[]"}],"name":"rebalanceWithdrawal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"reportRewardEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"reportSlashingEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingManager","type":"address"},{"internalType":"address","name":"validator","type":"address"}],"name":"setDelegation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSlashing","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"performanceScore","type":"uint256"}],"name":"updateValidatorPerformance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"validatorActiveState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"validatorAt","outputs":[{"internalType":"address","name":"validator","type":"address"},{"components":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"performanceScore","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct IValidatorManager.Validator","name":"data","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"validatorBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"validatorCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"validatorInfo","outputs":[{"components":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"performanceScore","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct IValidatorManager.Validator","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"validatorLastUpdateTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validatorPerformance","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"performanceScore","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validatorRebalanceRequests","outputs":[{"internalType":"address","name":"staking","type":"address"},{"internalType":"address","name":"validator","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validatorRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"validatorScores","outputs":[{"internalType":"uint256","name":"performanceScore","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validatorSlashing","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6080806040523460d0577ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460ff8160401c1660c1576002600160401b03196001600160401b03821601605c575b604051612aea90816100d58239f35b6001600160401b0319166001600160401b039081177ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005581527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a15f80604d565b63f92ee8a960e01b5f5260045ffd5b5f80fdfe6080806040526004361015610012575f80fd5b5f905f3560e01c90816301ffc9a714611e15575080630d2bd90914611da95780630e15561a14611d8c5780630eb9acea14611a805780630f43a67714611a6257806319363ad3146118f0578063248a9ca3146118c95780632b293768146117f45780632f2ff15d146117c257806332e0aa1f146116e057806336568abe1461169b57806337ce96ac146115d55780634db69d261461159e5780634f1811dd1461151f57806357afa91c146114be578063631f15a91461149a5780637623a74e1461134a578063825b747714611277578063886f1195146112505780638ac7834b146111ff5780638e87ce2d146111cb5780638f50bd13146111885780639010d07c1461113657806391d14854146110e0578063a217fddf146110c4578063a3246ad314611008578063aaa54e0d14610ec7578063b1845c5614610e8e578063b46e552014610cbd578063ba50b87914610b14578063bfc69e1c14610aec578063bffe348614610aab578063ca15c87314610a75578063d547741f14610a3a578063da13ffbf14610a01578063e1f1c4a7146109e4578063e47c355b1461062d578063ec87621c14610605578063f30720d6146105e7578063f5a9f94a146105815763f8c8765e146101e1575f80fd5b3461057e57608036600319011261057e576101fa611e82565b610202611e98565b90604435906001600160a01b0382169081830361057a576064356001600160a01b0381169390849003610576575f80516020612a95833981519152549460ff8660401c16159567ffffffffffffffff81168015908161056e575b6001149081610564575b15908161055b575b5061054c5767ffffffffffffffff1981166001175f80516020612a958339815191525586610520575b506001600160a01b0383169283156104e3576001600160a01b03821691821561049e57851561046057861561041b57610315946102ff61030a936102d96128bc565b6102e16128bc565b6102e96128bc565b60015f80516020612a558339815191525561257c565b6103f3575b50612618565b6103be575b506126be565b610389575b5082546001600160a01b0319161782556103315780f35b68ff0000000000000000195f80516020612a9583398151915254165f80516020612a95833981519152557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a180f35b6103b7905f80516020612a7583398151915285525f805160206129f583398151915260205260408520612987565b505f61031a565b6103ec905f80516020612a1583398151915288525f805160206129f583398151915260205260408820612987565b505f61030f565b610414908a80525f805160206129f583398151915260205260408b20612987565b505f610304565b60405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207061757365722072656769737472790000000000000000006044820152606490fd5b60405162461bcd60e51b8152602060048201526016602482015275496e76616c6964206f7261636c65206164647265737360501b6044820152606490fd5b60405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206d616e6167657220616464726573730000000000000000006044820152606490fd5b60405162461bcd60e51b8152602060048201526015602482015274496e76616c69642061646d696e206164647265737360581b6044820152606490fd5b68ffffffffffffffffff191668010000000000000001175f80516020612a95833981519152555f610297565b63f92ee8a960e01b8852600488fd5b9050155f61026e565b303b159150610266565b88915061025c565b8580fd5b8480fd5b80fd5b503461057e57602036600319011261057e576020806105dd6105d76105d26001600160a01b036105af611e82565b166105cd6105c8825f52600a60205260405f2054151590565b6120c3565b612538565b611edf565b5061208c565b0151604051908152f35b503461057e578060031936011261057e576020600154604051908152f35b503461057e578060031936011261057e5760206040515f80516020612a158339815191528152f35b503461057e57606036600319011261057e57610647611e82565b9060243567ffffffffffffffff81116109e057610668903690600401611eae565b9260443567ffffffffffffffff81116109dc57610689903690600401611eae565b8454604051635b14f18360e01b8152306004820152919492939190602090829060249082906001600160a01b03165afa9081156109d157906106d39187916109a2575b5015611f95565b6106db6121d9565b6106e3612211565b83860361096b578515610937576001600160a01b0316845b8681106107e05750803b1561057a576040519363c2ef1d9360e01b855286604486016040600488015252606485019286975b8089106107b157505084830360031901602486015280835294955085946001600160fb1b038111610576578560208682968196829560051b809285830137010301925af180156107a657610791575b5060015f80516020612a558339815191525580f35b8161079b91611f5b565b61057e57805f61077c565b6040513d84823e3d90fd5b909384356001600160a01b038116908190036107dc576020828192600194520195019801979061072d565b8880fd5b6108066001600160a01b036107fe6107f9848b88611fd6565b611fe6565b16151561218d565b6108146107f9828986611fd6565b90610820818787611fd6565b359160018060a01b0316808852600d602052610840604089205415612141565b82156108f2577f6154de7bd286a60f27d1045c5314775291c7eaae5a4b57a2a792ec28d68eac35602060019461087e6108788561288b565b506120c3565b60405161088a81611f0f565b8781528281018581526040808301848152878f5260048652908e20925183546001600160a01b031990811660a08c901b8c900392831617855592518a8501805490941691161790915551600291909101556108e484612937565b50604051908152a2016106fb565b60405162461bcd60e51b815260206004820152601960248201527f496e76616c6964207769746864726177616c20616d6f756e74000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152600c60248201526b456d7074792061727261797360a01b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e098cadccee8d040dad2e6dac2e8c6d608b1b6044820152606490fd5b6109c4915060203d6020116109ca575b6109bc8183611f5b565b810190611f7d565b5f6106cc565b503d6109b2565b6040513d88823e3d90fd5b8380fd5b5080fd5b503461057e578060031936011261057e5760206040516127108152f35b503461057e57602036600319011261057e576020906040906001600160a01b03610a29611e82565b168152600683522054604051908152f35b503461057e57604036600319011261057e57610a71600435610a5a611e98565b90610a6c610a678261204a565b6122c9565b612355565b5080f35b503461057e57602036600319011261057e57604060209160043581525f805160206129f583398151915283522054604051908152f35b503461057e57602036600319011261057e576020906001600160a01b03610ad0611e82565b16815260038252604060018060a01b0391205416604051908152f35b503461057e578060031936011261057e5760206040515f80516020612a758339815191528152f35b503461057e57602036600319011261057e57610b2e611e82565b8154604051635b14f18360e01b815230600482015290602090829060249082906001600160a01b03165afa8015610cb257610b709184916109a2575015611f95565b610b786121d9565b6001600160a01b03165f818152600a6020526040902054610b9a9015156120c3565b5f80516020612a1583398151915282525f80516020612a3583398151915260209081526040808420335f908152925290205460ff1615610c7c576003610bec6105d2610be58461288b565b91906120c3565b5001805460ff811615610c375760ff191690557f23d934bfe7f1275bc6fd70432159c9cc1c0075d069f89da6a40f43bfe7a94ed38280a260015f80516020612a558339815191525580f35b60405162461bcd60e51b815260206004820152601a60248201527f56616c696461746f7220616c726561647920696e6163746976650000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b6044820152606490fd5b6040513d85823e3d90fd5b503461057e57602036600319011261057e57610cd7611e82565b8154604051635b14f18360e01b815230600482015290602090829060249082906001600160a01b03165afa8015610cb257610d199184916109a2575015611f95565b610d21612211565b6001600160a01b0316610d3581151561218d565b610d4a815f52600a60205260405f2054151590565b610e4957604051610d5a81611f3f565b828152602081019083825260408101428152606082019260018452600854600160401b811015610e3557806001610d949201600855611edf565b939093610e2157906003939291518355516001830155516002820155019051151560ff801983541691161790556008545f198101908111610e0d57818352600b6020526040832055610de5816128e7565b507fb2b8c5f713f27009f7a78ec2167999c472e5ee8bc591102da17bc4a6551236c88280a280f35b634e487b7160e01b83526011600452602483fd5b634e487b7160e01b87526004879052602487fd5b634e487b7160e01b87526041600452602487fd5b60405162461bcd60e51b815260206004820152601860248201527f56616c696461746f7220616c72656164792065786973747300000000000000006044820152606490fd5b503461057e57602036600319011261057e576020906040906001600160a01b03610eb6611e82565b168152600783522054604051908152f35b503461057e57604036600319011261057e57610ee1611e82565b610ee9611e98565b8254604051635b14f18360e01b815230600482015291929190602090829060249082906001600160a01b03165afa8015610ffd57610f2e9185916109a2575015611f95565b610f36612211565b610f47610f428361210f565b612007565b6001600160a01b0316908115610fb8578183526003602081815260408086205485875292909152842080546001600160a01b0319166001600160a01b03938416908117909155929116907f5cbf8b4dd601c76e8851d991825e8d0d29d914f78f40fcc8ebddd97d913f149c8480a480f35b60405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207374616b696e67206d616e616765720000000000000000006044820152606490fd5b6040513d86823e3d90fd5b503461057e57602036600319011261057e5760043581525f805160206129f583398151915260205260408120604051908160208254918281520190819285526020852090855b8181106110ae5750505082611064910383611f5b565b604051928392602084019060208552518091526040840192915b81811061108c575050500390f35b82516001600160a01b031684528594506020938401939092019160010161107e565b825484526020909301926001928301920161104e565b503461057e578060031936011261057e57602090604051908152f35b503461057e57604036600319011261057e5760406110fc611e98565b9160043581525f80516020612a35833981519152602052209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b503461057e57604036600319011261057e5761116f60209160043581525f805160206129f5833981519152835260406024359120612397565b905460405160039290921b1c6001600160a01b03168152f35b503461057e57602036600319011261057e5760206111c16001600160a01b036111af611e82565b165f52600d60205260405f2054151590565b6040519015158152f35b503461057e57602036600319011261057e5760206111f56105d26001600160a01b036105af611e82565b5054604051908152f35b503461057e57602036600319011261057e576060906040906001600160a01b03611227611e82565b168152600560205220805490600260018201549101549060405192835260208301526040820152f35b503461057e578060031936011261057e57546040516001600160a01b039091168152602090f35b503461057e57604036600319011261057e57611291611e82565b6024359061129d61226d565b6112a9610f428261210f565b811561130d5760207fd36143b3ca1520d3b9e429976a829d6bc40c6b097d16399efae03a37f310ae49916112df84600254611ffa565b60025560018060a01b0316928385526007825260408520611301828254611ffa565b9055604051908152a280f35b60405162461bcd60e51b8152602060048201526015602482015274125b9d985b1a59081c995dd85c9908185b5bdd5b9d605a1b6044820152606490fd5b503461057e57602036600319011261057e57611364611e82565b8154604051635b14f18360e01b815230600482015290602090829060249082906001600160a01b03165afa8015610cb2576113a69184916109a2575015611f95565b6113ae6121d9565b6113b6612211565b6001600160a01b03165f818152600a60205260409020546113d89015156120c3565b60036113e96105d2610be58461288b565b5001805460ff811661145557600190611416611410855f52600d60205260405f2054151590565b15612141565b60ff19161790557f65cf6d2b9cf96b1ffffa32041ec7c360f76b05f5f4f5e13c7f19495246d6f4f48280a260015f80516020612a558339815191525580f35b60405162461bcd60e51b815260206004820152601860248201527f56616c696461746f7220616c72656164792061637469766500000000000000006044820152606490fd5b503461057e57602036600319011261057e5760206111c16114b9611e82565b61210f565b503461057e57602036600319011261057e576060906040906001600160a01b036114e6611e82565b16815260046020522060018060a01b0381541690600260018060a01b036001830154169101549060405192835260208301526040820152f35b503461057e57602036600319011261057e57608061156f6105d76105d2611544611e82565b61154c612068565b506001600160a01b03165f818152600a60205260409020546105cd9015156120c3565b61159c60405180926060809180518452602081015160208501526040810151604085015201511515910152565bf35b503461057e57602036600319011261057e57602060026115ca6105d26001600160a01b036105af611e82565b500154604051908152f35b503461057e57604036600319011261057e576115ef611e82565b602435906115fb61226d565b611607610f428261210f565b811561165f5760207f63ce9927e6e9c82f626f47fe72a77d38f6d8c9bf9d49e4584acf3e90b1946a1a9161163d84600154611ffa565b60015560018060a01b0316928385526006825260408520611301828254611ffa565b60405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a59081cdb185cda08185b5bdd5b9d60621b6044820152606490fd5b503461057e57604036600319011261057e576116b5611e98565b336001600160a01b038216036116d157610a7190600435612355565b63334bd91960e11b8252600482fd5b503461057e57602036600319011261057e57600435906116fe612068565b50600854821015611787576009548210156117735761159c61173c6105d760a09460098552806020862001548560031b1c809552600b602052611edf565b60405192600180861b0316835260208301906060809180518452602081015160208501526040810151604085015201511515910152565b634e487b7160e01b81526032600452602490fd5b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606490fd5b503461057e57604036600319011261057e57610a716004356117e2611e98565b906117ef610a678261204a565b61230f565b503461057e57602036600319011261057e576001600160a01b03611816611e82565b168152600360205260409020546001600160a01b031680156118905761183b8161210f565b1561184b57602090604051908152f35b60405162461bcd60e51b815260206004820152601e60248201527f44656c6567617465642076616c696461746f72206e6f742061637469766500006044820152606490fd5b60405162461bcd60e51b8152602060048201526011602482015270139bc819195b1959d85d1a5bdb881cd95d607a1b6044820152606490fd5b503461057e57602036600319011261057e5760206118e860043561204a565b604051908152f35b503461057e57606036600319011261057e5761190a611e82565b8154604051635b14f18360e01b8152306004820152604435926024803593919291602091839182906001600160a01b03165afa8015611a57576119549186916109a2575015611f95565b61195c61226d565b611968610f428261210f565b6127108311611a1a576001600160a01b0316916002906119aa61198a85612538565b8461199482611edf565b50558260016119a283611edf565b500155611edf565b508242910155604051926119bd84611f0f565b835260208301908152604083019042825284865260056020526040862093518455516001840155519101557f5fccbb07a0dab375247a9d144c14a3db4061295b18e45d352478c9f6edb6a3c860408051428152436020820152a280f35b60405162461bcd60e51b815260206004820152601560248201527453636f72652065786365656473206d6178696d756d60581b6044820152606490fd5b6040513d87823e3d90fd5b503461057e578060031936011261057e576020600854604051908152f35b5034611ba7576040366003190112611ba757611a9a611e82565b60243567ffffffffffffffff8111611ba757611aba903690600401611eae565b5f54604051635b14f18360e01b815230600482015291939190602090829060249082906001600160a01b03165afa8015611b9c57611aff915f916109a2575015611f95565b611b076121d9565b611b0f612211565b600c5415611d51578215611d1e576001600160a01b0316915f918291905b818310611bab5750505080611b52575b8260015f80516020612a558339815191525580f35b813b15611ba7575f9160248392604051948593849263296e882960e21b845260048401525af18015611b9c57611b89575b80611b3d565b611b9591505f90611f5b565b5f80611b83565b6040513d5f823e3d90fd5b5f80fd5b91929091906001600160a01b03611bc66107f9868686611fd6565b1693611bdd855f52600d60205260405f2054151590565b15611ce457845f52600460205260405f20948660405196611bfd88611f0f565b80546001600160a01b03908116808a52600183015490911660208a0152600290910154604090980197885203611c91577f3fb733198c279e91bafa2fdf515f5ef58924785e1326715671cc7b4c92d743906020611c5e600195895190611ffa565b97835f52600482525f60026040822082815582898201550155611c80846123ac565b5051604051908152a2019190611b2d565b60405162461bcd60e51b815260206004820152602560248201527f496e76616c6964207374616b696e67206d616e6167657220666f7220726562616044820152646c616e636560d81b6064820152608490fd5b60405162461bcd60e51b8152602060048201526012602482015271139bc81c195b991a5b99c81c995c5d595cdd60721b6044820152606490fd5b60405162461bcd60e51b815260206004820152600b60248201526a456d70747920617272617960a81b6044820152606490fd5b60405162461bcd60e51b81526020600482015260136024820152724e6f2070656e64696e6720726571756573747360681b6044820152606490fd5b34611ba7575f366003190112611ba7576020600254604051908152f35b34611ba7575f366003190112611ba7575f6008545f5b818110611dd157602083604051908152f35b60ff6003611dde83611edf565b50015416611def575b600101611dbf565b915f198114611e015760010191611de7565b634e487b7160e01b5f52601160045260245ffd5b34611ba7576020366003190112611ba7576004359063ffffffff60e01b8216809203611ba757602091635a05180f60e01b8114908115611e57575b5015158152f35b637965db0b60e01b811491508115611e71575b5083611e50565b6301ffc9a760e01b14905083611e6a565b600435906001600160a01b0382168203611ba757565b602435906001600160a01b0382168203611ba757565b9181601f84011215611ba75782359167ffffffffffffffff8311611ba7576020808501948460051b010111611ba757565b600854811015611efb5760085f5260205f209060021b01905f90565b634e487b7160e01b5f52603260045260245ffd5b6060810190811067ffffffffffffffff821117611f2b57604052565b634e487b7160e01b5f52604160045260245ffd5b6080810190811067ffffffffffffffff821117611f2b57604052565b90601f8019910116810190811067ffffffffffffffff821117611f2b57604052565b90816020910312611ba757518015158103611ba75790565b15611f9c57565b60405162461bcd60e51b815260206004820152601260248201527110dbdb9d1c9858dd081a5cc81c185d5cd95960721b6044820152606490fd5b9190811015611efb5760051b0190565b356001600160a01b0381168103611ba75790565b91908201809211611e0157565b1561200e57565b60405162461bcd60e51b815260206004820152601460248201527356616c696461746f72206e6f742061637469766560601b6044820152606490fd5b5f525f80516020612a35833981519152602052600160405f20015490565b6040519061207582611f3f565b5f6060838281528260208201528260408201520152565b9060405161209981611f3f565b606060ff600383958054855260018101546020860152600281015460408601520154161515910152565b156120ca57565b60405162461bcd60e51b815260206004820152601860248201527f56616c696461746f7220646f6573206e6f7420657869737400000000000000006044820152606490fd5b600361213a6105d260ff9360018060a01b03166105cd6105c8825f52600a60205260405f2054151590565b5001541690565b1561214857565b60405162461bcd60e51b815260206004820152601f60248201527f56616c696461746f72206861732070656e64696e6720726562616c616e6365006044820152606490fd5b1561219457565b60405162461bcd60e51b815260206004820152601960248201527f496e76616c69642076616c696461746f722061646472657373000000000000006044820152606490fd5b60025f80516020612a5583398151915254146122025760025f80516020612a5583398151915255565b633ee5aeb560e01b5f5260045ffd5b335f9081527f06484cc59dc38e4f67c31122333a17ca81b3ca18cdf02bfc298072fa52b0316a602052604090205460ff161561224957565b63e2517d3f60e01b5f52336004525f80516020612a1583398151915260245260445ffd5b335f9081527f6a07288dad4cb198070ae9ab0d91c908f3652738923841b35a5b72d3571a1cec602052604090205460ff16156122a557565b63e2517d3f60e01b5f52336004525f80516020612a7583398151915260245260445ffd5b5f8181525f80516020612a358339815191526020908152604080832033845290915290205460ff16156122f95750565b63e2517d3f60e01b5f523360045260245260445ffd5b6123198282612764565b918261232457505090565b5f9182525f805160206129f58339815191526020526040909120612351916001600160a01b031690612987565b5090565b61235f82826127ef565b918261236a57505090565b5f9182525f805160206129f58339815191526020526040909120612351916001600160a01b031690612487565b8054821015611efb575f5260205f2001905f90565b5f818152600d60205260409020548015612481575f198101818111611e0157600c545f19810191908211611e0157818103612433575b505050600c54801561241f575f19016123fc81600c612397565b8154905f199060031b1b19169055600c555f52600d6020525f6040812055600190565b634e487b7160e01b5f52603160045260245ffd5b61246b61244461245593600c612397565b90549060031b1c928392600c612397565b819391549060031b91821b915f19901b19161790565b90555f52600d60205260405f20555f80806123e2565b50505f90565b906001820191815f528260205260405f20548015155f14612530575f198101818111611e015782545f19810191908211611e01578181036124fb575b5050508054801561241f575f1901906124dc8282612397565b8154905f199060031b1b19169055555f526020525f6040812055600190565b61251b61250b6124559386612397565b90549060031b1c92839286612397565b90555f528360205260405f20555f80806124c3565b505050505f90565b805f52600b60205260405f205490811580612568575b612556575090565b63015ab34360e11b5f5260045260245ffd5b50805f52600a60205260405f20541561254e565b6001600160a01b0381165f9081527fb7db2dd08fcb62d0c9e08c51941cae53c267786a0b75803fb7960902fc8ef97d602052604090205460ff16612613576001600160a01b03165f8181527fb7db2dd08fcb62d0c9e08c51941cae53c267786a0b75803fb7960902fc8ef97d60205260408120805460ff191660011790553391905f805160206129d58339815191528180a4600190565b505f90565b6001600160a01b0381165f9081527f06484cc59dc38e4f67c31122333a17ca81b3ca18cdf02bfc298072fa52b0316a602052604090205460ff16612613576001600160a01b03165f8181527f06484cc59dc38e4f67c31122333a17ca81b3ca18cdf02bfc298072fa52b0316a60205260408120805460ff191660011790553391905f80516020612a15833981519152905f805160206129d58339815191529080a4600190565b6001600160a01b0381165f9081527f6a07288dad4cb198070ae9ab0d91c908f3652738923841b35a5b72d3571a1cec602052604090205460ff16612613576001600160a01b03165f8181527f6a07288dad4cb198070ae9ab0d91c908f3652738923841b35a5b72d3571a1cec60205260408120805460ff191660011790553391905f80516020612a75833981519152905f805160206129d58339815191529080a4600190565b5f8181525f80516020612a35833981519152602090815260408083206001600160a01b038616845290915290205460ff16612481575f8181525f80516020612a35833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291905f805160206129d58339815191529080a4600190565b5f8181525f80516020612a35833981519152602090815260408083206001600160a01b038616845290915290205460ff1615612481575f8181525f80516020612a35833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b805f52600b60205260405f205480155f146128b457505f52600a60205260405f20541515905f90565b600192909150565b60ff5f80516020612a958339815191525460401c16156128d857565b631afcd79f60e31b5f5260045ffd5b805f52600a60205260405f2054155f1461261357600954600160401b811015611f2b576129206124558260018594016009556009612397565b9055600954905f52600a60205260405f2055600190565b805f52600d60205260405f2054155f1461261357600c54600160401b811015611f2b57612970612455826001859401600c55600c612397565b9055600c54905f52600d60205260405f2055600190565b5f82815260018201602052604090205461248157805490600160401b821015611f2b57826129bf612455846001809601855584612397565b90558054925f520160205260405f205560019056fe2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0dc1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e82371705932000241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0802dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00ced6982f480260bdd8ad5cb18ff2854f0306d78d904ad6cc107e8f3a0f526c18f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00a26469706673582212201fa37769918cc943d916ff9602c6797854517220ef2c16ad9fa7a3883db04d1664736f6c634300081a0033
Deployed Bytecode
0x6080806040526004361015610012575f80fd5b5f905f3560e01c90816301ffc9a714611e15575080630d2bd90914611da95780630e15561a14611d8c5780630eb9acea14611a805780630f43a67714611a6257806319363ad3146118f0578063248a9ca3146118c95780632b293768146117f45780632f2ff15d146117c257806332e0aa1f146116e057806336568abe1461169b57806337ce96ac146115d55780634db69d261461159e5780634f1811dd1461151f57806357afa91c146114be578063631f15a91461149a5780637623a74e1461134a578063825b747714611277578063886f1195146112505780638ac7834b146111ff5780638e87ce2d146111cb5780638f50bd13146111885780639010d07c1461113657806391d14854146110e0578063a217fddf146110c4578063a3246ad314611008578063aaa54e0d14610ec7578063b1845c5614610e8e578063b46e552014610cbd578063ba50b87914610b14578063bfc69e1c14610aec578063bffe348614610aab578063ca15c87314610a75578063d547741f14610a3a578063da13ffbf14610a01578063e1f1c4a7146109e4578063e47c355b1461062d578063ec87621c14610605578063f30720d6146105e7578063f5a9f94a146105815763f8c8765e146101e1575f80fd5b3461057e57608036600319011261057e576101fa611e82565b610202611e98565b90604435906001600160a01b0382169081830361057a576064356001600160a01b0381169390849003610576575f80516020612a95833981519152549460ff8660401c16159567ffffffffffffffff81168015908161056e575b6001149081610564575b15908161055b575b5061054c5767ffffffffffffffff1981166001175f80516020612a958339815191525586610520575b506001600160a01b0383169283156104e3576001600160a01b03821691821561049e57851561046057861561041b57610315946102ff61030a936102d96128bc565b6102e16128bc565b6102e96128bc565b60015f80516020612a558339815191525561257c565b6103f3575b50612618565b6103be575b506126be565b610389575b5082546001600160a01b0319161782556103315780f35b68ff0000000000000000195f80516020612a9583398151915254165f80516020612a95833981519152557fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2602060405160018152a180f35b6103b7905f80516020612a7583398151915285525f805160206129f583398151915260205260408520612987565b505f61031a565b6103ec905f80516020612a1583398151915288525f805160206129f583398151915260205260408820612987565b505f61030f565b610414908a80525f805160206129f583398151915260205260408b20612987565b505f610304565b60405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207061757365722072656769737472790000000000000000006044820152606490fd5b60405162461bcd60e51b8152602060048201526016602482015275496e76616c6964206f7261636c65206164647265737360501b6044820152606490fd5b60405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206d616e6167657220616464726573730000000000000000006044820152606490fd5b60405162461bcd60e51b8152602060048201526015602482015274496e76616c69642061646d696e206164647265737360581b6044820152606490fd5b68ffffffffffffffffff191668010000000000000001175f80516020612a95833981519152555f610297565b63f92ee8a960e01b8852600488fd5b9050155f61026e565b303b159150610266565b88915061025c565b8580fd5b8480fd5b80fd5b503461057e57602036600319011261057e576020806105dd6105d76105d26001600160a01b036105af611e82565b166105cd6105c8825f52600a60205260405f2054151590565b6120c3565b612538565b611edf565b5061208c565b0151604051908152f35b503461057e578060031936011261057e576020600154604051908152f35b503461057e578060031936011261057e5760206040515f80516020612a158339815191528152f35b503461057e57606036600319011261057e57610647611e82565b9060243567ffffffffffffffff81116109e057610668903690600401611eae565b9260443567ffffffffffffffff81116109dc57610689903690600401611eae565b8454604051635b14f18360e01b8152306004820152919492939190602090829060249082906001600160a01b03165afa9081156109d157906106d39187916109a2575b5015611f95565b6106db6121d9565b6106e3612211565b83860361096b578515610937576001600160a01b0316845b8681106107e05750803b1561057a576040519363c2ef1d9360e01b855286604486016040600488015252606485019286975b8089106107b157505084830360031901602486015280835294955085946001600160fb1b038111610576578560208682968196829560051b809285830137010301925af180156107a657610791575b5060015f80516020612a558339815191525580f35b8161079b91611f5b565b61057e57805f61077c565b6040513d84823e3d90fd5b909384356001600160a01b038116908190036107dc576020828192600194520195019801979061072d565b8880fd5b6108066001600160a01b036107fe6107f9848b88611fd6565b611fe6565b16151561218d565b6108146107f9828986611fd6565b90610820818787611fd6565b359160018060a01b0316808852600d602052610840604089205415612141565b82156108f2577f6154de7bd286a60f27d1045c5314775291c7eaae5a4b57a2a792ec28d68eac35602060019461087e6108788561288b565b506120c3565b60405161088a81611f0f565b8781528281018581526040808301848152878f5260048652908e20925183546001600160a01b031990811660a08c901b8c900392831617855592518a8501805490941691161790915551600291909101556108e484612937565b50604051908152a2016106fb565b60405162461bcd60e51b815260206004820152601960248201527f496e76616c6964207769746864726177616c20616d6f756e74000000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152600c60248201526b456d7074792061727261797360a01b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e098cadccee8d040dad2e6dac2e8c6d608b1b6044820152606490fd5b6109c4915060203d6020116109ca575b6109bc8183611f5b565b810190611f7d565b5f6106cc565b503d6109b2565b6040513d88823e3d90fd5b8380fd5b5080fd5b503461057e578060031936011261057e5760206040516127108152f35b503461057e57602036600319011261057e576020906040906001600160a01b03610a29611e82565b168152600683522054604051908152f35b503461057e57604036600319011261057e57610a71600435610a5a611e98565b90610a6c610a678261204a565b6122c9565b612355565b5080f35b503461057e57602036600319011261057e57604060209160043581525f805160206129f583398151915283522054604051908152f35b503461057e57602036600319011261057e576020906001600160a01b03610ad0611e82565b16815260038252604060018060a01b0391205416604051908152f35b503461057e578060031936011261057e5760206040515f80516020612a758339815191528152f35b503461057e57602036600319011261057e57610b2e611e82565b8154604051635b14f18360e01b815230600482015290602090829060249082906001600160a01b03165afa8015610cb257610b709184916109a2575015611f95565b610b786121d9565b6001600160a01b03165f818152600a6020526040902054610b9a9015156120c3565b5f80516020612a1583398151915282525f80516020612a3583398151915260209081526040808420335f908152925290205460ff1615610c7c576003610bec6105d2610be58461288b565b91906120c3565b5001805460ff811615610c375760ff191690557f23d934bfe7f1275bc6fd70432159c9cc1c0075d069f89da6a40f43bfe7a94ed38280a260015f80516020612a558339815191525580f35b60405162461bcd60e51b815260206004820152601a60248201527f56616c696461746f7220616c726561647920696e6163746976650000000000006044820152606490fd5b60405162461bcd60e51b815260206004820152600e60248201526d139bdd08185d5d1a1bdc9a5e995960921b6044820152606490fd5b6040513d85823e3d90fd5b503461057e57602036600319011261057e57610cd7611e82565b8154604051635b14f18360e01b815230600482015290602090829060249082906001600160a01b03165afa8015610cb257610d199184916109a2575015611f95565b610d21612211565b6001600160a01b0316610d3581151561218d565b610d4a815f52600a60205260405f2054151590565b610e4957604051610d5a81611f3f565b828152602081019083825260408101428152606082019260018452600854600160401b811015610e3557806001610d949201600855611edf565b939093610e2157906003939291518355516001830155516002820155019051151560ff801983541691161790556008545f198101908111610e0d57818352600b6020526040832055610de5816128e7565b507fb2b8c5f713f27009f7a78ec2167999c472e5ee8bc591102da17bc4a6551236c88280a280f35b634e487b7160e01b83526011600452602483fd5b634e487b7160e01b87526004879052602487fd5b634e487b7160e01b87526041600452602487fd5b60405162461bcd60e51b815260206004820152601860248201527f56616c696461746f7220616c72656164792065786973747300000000000000006044820152606490fd5b503461057e57602036600319011261057e576020906040906001600160a01b03610eb6611e82565b168152600783522054604051908152f35b503461057e57604036600319011261057e57610ee1611e82565b610ee9611e98565b8254604051635b14f18360e01b815230600482015291929190602090829060249082906001600160a01b03165afa8015610ffd57610f2e9185916109a2575015611f95565b610f36612211565b610f47610f428361210f565b612007565b6001600160a01b0316908115610fb8578183526003602081815260408086205485875292909152842080546001600160a01b0319166001600160a01b03938416908117909155929116907f5cbf8b4dd601c76e8851d991825e8d0d29d914f78f40fcc8ebddd97d913f149c8480a480f35b60405162461bcd60e51b815260206004820152601760248201527f496e76616c6964207374616b696e67206d616e616765720000000000000000006044820152606490fd5b6040513d86823e3d90fd5b503461057e57602036600319011261057e5760043581525f805160206129f583398151915260205260408120604051908160208254918281520190819285526020852090855b8181106110ae5750505082611064910383611f5b565b604051928392602084019060208552518091526040840192915b81811061108c575050500390f35b82516001600160a01b031684528594506020938401939092019160010161107e565b825484526020909301926001928301920161104e565b503461057e578060031936011261057e57602090604051908152f35b503461057e57604036600319011261057e5760406110fc611e98565b9160043581525f80516020612a35833981519152602052209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b503461057e57604036600319011261057e5761116f60209160043581525f805160206129f5833981519152835260406024359120612397565b905460405160039290921b1c6001600160a01b03168152f35b503461057e57602036600319011261057e5760206111c16001600160a01b036111af611e82565b165f52600d60205260405f2054151590565b6040519015158152f35b503461057e57602036600319011261057e5760206111f56105d26001600160a01b036105af611e82565b5054604051908152f35b503461057e57602036600319011261057e576060906040906001600160a01b03611227611e82565b168152600560205220805490600260018201549101549060405192835260208301526040820152f35b503461057e578060031936011261057e57546040516001600160a01b039091168152602090f35b503461057e57604036600319011261057e57611291611e82565b6024359061129d61226d565b6112a9610f428261210f565b811561130d5760207fd36143b3ca1520d3b9e429976a829d6bc40c6b097d16399efae03a37f310ae49916112df84600254611ffa565b60025560018060a01b0316928385526007825260408520611301828254611ffa565b9055604051908152a280f35b60405162461bcd60e51b8152602060048201526015602482015274125b9d985b1a59081c995dd85c9908185b5bdd5b9d605a1b6044820152606490fd5b503461057e57602036600319011261057e57611364611e82565b8154604051635b14f18360e01b815230600482015290602090829060249082906001600160a01b03165afa8015610cb2576113a69184916109a2575015611f95565b6113ae6121d9565b6113b6612211565b6001600160a01b03165f818152600a60205260409020546113d89015156120c3565b60036113e96105d2610be58461288b565b5001805460ff811661145557600190611416611410855f52600d60205260405f2054151590565b15612141565b60ff19161790557f65cf6d2b9cf96b1ffffa32041ec7c360f76b05f5f4f5e13c7f19495246d6f4f48280a260015f80516020612a558339815191525580f35b60405162461bcd60e51b815260206004820152601860248201527f56616c696461746f7220616c72656164792061637469766500000000000000006044820152606490fd5b503461057e57602036600319011261057e5760206111c16114b9611e82565b61210f565b503461057e57602036600319011261057e576060906040906001600160a01b036114e6611e82565b16815260046020522060018060a01b0381541690600260018060a01b036001830154169101549060405192835260208301526040820152f35b503461057e57602036600319011261057e57608061156f6105d76105d2611544611e82565b61154c612068565b506001600160a01b03165f818152600a60205260409020546105cd9015156120c3565b61159c60405180926060809180518452602081015160208501526040810151604085015201511515910152565bf35b503461057e57602036600319011261057e57602060026115ca6105d26001600160a01b036105af611e82565b500154604051908152f35b503461057e57604036600319011261057e576115ef611e82565b602435906115fb61226d565b611607610f428261210f565b811561165f5760207f63ce9927e6e9c82f626f47fe72a77d38f6d8c9bf9d49e4584acf3e90b1946a1a9161163d84600154611ffa565b60015560018060a01b0316928385526006825260408520611301828254611ffa565b60405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a59081cdb185cda08185b5bdd5b9d60621b6044820152606490fd5b503461057e57604036600319011261057e576116b5611e98565b336001600160a01b038216036116d157610a7190600435612355565b63334bd91960e11b8252600482fd5b503461057e57602036600319011261057e57600435906116fe612068565b50600854821015611787576009548210156117735761159c61173c6105d760a09460098552806020862001548560031b1c809552600b602052611edf565b60405192600180861b0316835260208301906060809180518452602081015160208501526040810151604085015201511515910152565b634e487b7160e01b81526032600452602490fd5b60405162461bcd60e51b8152602060048201526013602482015272496e646578206f7574206f6620626f756e647360681b6044820152606490fd5b503461057e57604036600319011261057e57610a716004356117e2611e98565b906117ef610a678261204a565b61230f565b503461057e57602036600319011261057e576001600160a01b03611816611e82565b168152600360205260409020546001600160a01b031680156118905761183b8161210f565b1561184b57602090604051908152f35b60405162461bcd60e51b815260206004820152601e60248201527f44656c6567617465642076616c696461746f72206e6f742061637469766500006044820152606490fd5b60405162461bcd60e51b8152602060048201526011602482015270139bc819195b1959d85d1a5bdb881cd95d607a1b6044820152606490fd5b503461057e57602036600319011261057e5760206118e860043561204a565b604051908152f35b503461057e57606036600319011261057e5761190a611e82565b8154604051635b14f18360e01b8152306004820152604435926024803593919291602091839182906001600160a01b03165afa8015611a57576119549186916109a2575015611f95565b61195c61226d565b611968610f428261210f565b6127108311611a1a576001600160a01b0316916002906119aa61198a85612538565b8461199482611edf565b50558260016119a283611edf565b500155611edf565b508242910155604051926119bd84611f0f565b835260208301908152604083019042825284865260056020526040862093518455516001840155519101557f5fccbb07a0dab375247a9d144c14a3db4061295b18e45d352478c9f6edb6a3c860408051428152436020820152a280f35b60405162461bcd60e51b815260206004820152601560248201527453636f72652065786365656473206d6178696d756d60581b6044820152606490fd5b6040513d87823e3d90fd5b503461057e578060031936011261057e576020600854604051908152f35b5034611ba7576040366003190112611ba757611a9a611e82565b60243567ffffffffffffffff8111611ba757611aba903690600401611eae565b5f54604051635b14f18360e01b815230600482015291939190602090829060249082906001600160a01b03165afa8015611b9c57611aff915f916109a2575015611f95565b611b076121d9565b611b0f612211565b600c5415611d51578215611d1e576001600160a01b0316915f918291905b818310611bab5750505080611b52575b8260015f80516020612a558339815191525580f35b813b15611ba7575f9160248392604051948593849263296e882960e21b845260048401525af18015611b9c57611b89575b80611b3d565b611b9591505f90611f5b565b5f80611b83565b6040513d5f823e3d90fd5b5f80fd5b91929091906001600160a01b03611bc66107f9868686611fd6565b1693611bdd855f52600d60205260405f2054151590565b15611ce457845f52600460205260405f20948660405196611bfd88611f0f565b80546001600160a01b03908116808a52600183015490911660208a0152600290910154604090980197885203611c91577f3fb733198c279e91bafa2fdf515f5ef58924785e1326715671cc7b4c92d743906020611c5e600195895190611ffa565b97835f52600482525f60026040822082815582898201550155611c80846123ac565b5051604051908152a2019190611b2d565b60405162461bcd60e51b815260206004820152602560248201527f496e76616c6964207374616b696e67206d616e6167657220666f7220726562616044820152646c616e636560d81b6064820152608490fd5b60405162461bcd60e51b8152602060048201526012602482015271139bc81c195b991a5b99c81c995c5d595cdd60721b6044820152606490fd5b60405162461bcd60e51b815260206004820152600b60248201526a456d70747920617272617960a81b6044820152606490fd5b60405162461bcd60e51b81526020600482015260136024820152724e6f2070656e64696e6720726571756573747360681b6044820152606490fd5b34611ba7575f366003190112611ba7576020600254604051908152f35b34611ba7575f366003190112611ba7575f6008545f5b818110611dd157602083604051908152f35b60ff6003611dde83611edf565b50015416611def575b600101611dbf565b915f198114611e015760010191611de7565b634e487b7160e01b5f52601160045260245ffd5b34611ba7576020366003190112611ba7576004359063ffffffff60e01b8216809203611ba757602091635a05180f60e01b8114908115611e57575b5015158152f35b637965db0b60e01b811491508115611e71575b5083611e50565b6301ffc9a760e01b14905083611e6a565b600435906001600160a01b0382168203611ba757565b602435906001600160a01b0382168203611ba757565b9181601f84011215611ba75782359167ffffffffffffffff8311611ba7576020808501948460051b010111611ba757565b600854811015611efb5760085f5260205f209060021b01905f90565b634e487b7160e01b5f52603260045260245ffd5b6060810190811067ffffffffffffffff821117611f2b57604052565b634e487b7160e01b5f52604160045260245ffd5b6080810190811067ffffffffffffffff821117611f2b57604052565b90601f8019910116810190811067ffffffffffffffff821117611f2b57604052565b90816020910312611ba757518015158103611ba75790565b15611f9c57565b60405162461bcd60e51b815260206004820152601260248201527110dbdb9d1c9858dd081a5cc81c185d5cd95960721b6044820152606490fd5b9190811015611efb5760051b0190565b356001600160a01b0381168103611ba75790565b91908201809211611e0157565b1561200e57565b60405162461bcd60e51b815260206004820152601460248201527356616c696461746f72206e6f742061637469766560601b6044820152606490fd5b5f525f80516020612a35833981519152602052600160405f20015490565b6040519061207582611f3f565b5f6060838281528260208201528260408201520152565b9060405161209981611f3f565b606060ff600383958054855260018101546020860152600281015460408601520154161515910152565b156120ca57565b60405162461bcd60e51b815260206004820152601860248201527f56616c696461746f7220646f6573206e6f7420657869737400000000000000006044820152606490fd5b600361213a6105d260ff9360018060a01b03166105cd6105c8825f52600a60205260405f2054151590565b5001541690565b1561214857565b60405162461bcd60e51b815260206004820152601f60248201527f56616c696461746f72206861732070656e64696e6720726562616c616e6365006044820152606490fd5b1561219457565b60405162461bcd60e51b815260206004820152601960248201527f496e76616c69642076616c696461746f722061646472657373000000000000006044820152606490fd5b60025f80516020612a5583398151915254146122025760025f80516020612a5583398151915255565b633ee5aeb560e01b5f5260045ffd5b335f9081527f06484cc59dc38e4f67c31122333a17ca81b3ca18cdf02bfc298072fa52b0316a602052604090205460ff161561224957565b63e2517d3f60e01b5f52336004525f80516020612a1583398151915260245260445ffd5b335f9081527f6a07288dad4cb198070ae9ab0d91c908f3652738923841b35a5b72d3571a1cec602052604090205460ff16156122a557565b63e2517d3f60e01b5f52336004525f80516020612a7583398151915260245260445ffd5b5f8181525f80516020612a358339815191526020908152604080832033845290915290205460ff16156122f95750565b63e2517d3f60e01b5f523360045260245260445ffd5b6123198282612764565b918261232457505090565b5f9182525f805160206129f58339815191526020526040909120612351916001600160a01b031690612987565b5090565b61235f82826127ef565b918261236a57505090565b5f9182525f805160206129f58339815191526020526040909120612351916001600160a01b031690612487565b8054821015611efb575f5260205f2001905f90565b5f818152600d60205260409020548015612481575f198101818111611e0157600c545f19810191908211611e0157818103612433575b505050600c54801561241f575f19016123fc81600c612397565b8154905f199060031b1b19169055600c555f52600d6020525f6040812055600190565b634e487b7160e01b5f52603160045260245ffd5b61246b61244461245593600c612397565b90549060031b1c928392600c612397565b819391549060031b91821b915f19901b19161790565b90555f52600d60205260405f20555f80806123e2565b50505f90565b906001820191815f528260205260405f20548015155f14612530575f198101818111611e015782545f19810191908211611e01578181036124fb575b5050508054801561241f575f1901906124dc8282612397565b8154905f199060031b1b19169055555f526020525f6040812055600190565b61251b61250b6124559386612397565b90549060031b1c92839286612397565b90555f528360205260405f20555f80806124c3565b505050505f90565b805f52600b60205260405f205490811580612568575b612556575090565b63015ab34360e11b5f5260045260245ffd5b50805f52600a60205260405f20541561254e565b6001600160a01b0381165f9081527fb7db2dd08fcb62d0c9e08c51941cae53c267786a0b75803fb7960902fc8ef97d602052604090205460ff16612613576001600160a01b03165f8181527fb7db2dd08fcb62d0c9e08c51941cae53c267786a0b75803fb7960902fc8ef97d60205260408120805460ff191660011790553391905f805160206129d58339815191528180a4600190565b505f90565b6001600160a01b0381165f9081527f06484cc59dc38e4f67c31122333a17ca81b3ca18cdf02bfc298072fa52b0316a602052604090205460ff16612613576001600160a01b03165f8181527f06484cc59dc38e4f67c31122333a17ca81b3ca18cdf02bfc298072fa52b0316a60205260408120805460ff191660011790553391905f80516020612a15833981519152905f805160206129d58339815191529080a4600190565b6001600160a01b0381165f9081527f6a07288dad4cb198070ae9ab0d91c908f3652738923841b35a5b72d3571a1cec602052604090205460ff16612613576001600160a01b03165f8181527f6a07288dad4cb198070ae9ab0d91c908f3652738923841b35a5b72d3571a1cec60205260408120805460ff191660011790553391905f80516020612a75833981519152905f805160206129d58339815191529080a4600190565b5f8181525f80516020612a35833981519152602090815260408083206001600160a01b038616845290915290205460ff16612481575f8181525f80516020612a35833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291905f805160206129d58339815191529080a4600190565b5f8181525f80516020612a35833981519152602090815260408083206001600160a01b038616845290915290205460ff1615612481575f8181525f80516020612a35833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b805f52600b60205260405f205480155f146128b457505f52600a60205260405f20541515905f90565b600192909150565b60ff5f80516020612a958339815191525460401c16156128d857565b631afcd79f60e31b5f5260045ffd5b805f52600a60205260405f2054155f1461261357600954600160401b811015611f2b576129206124558260018594016009556009612397565b9055600954905f52600a60205260405f2055600190565b805f52600d60205260405f2054155f1461261357600c54600160401b811015611f2b57612970612455826001859401600c55600c612397565b9055600c54905f52600d60205260405f2055600190565b5f82815260018201602052604090205461248157805490600160401b821015611f2b57826129bf612455846001809601855584612397565b90558054925f520160205260405f205560019056fe2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0dc1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e82371705932000241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0802dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b6268009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00ced6982f480260bdd8ad5cb18ff2854f0306d78d904ad6cc107e8f3a0f526c18f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00a26469706673582212201fa37769918cc943d916ff9602c6797854517220ef2c16ad9fa7a3883db04d1664736f6c634300081a0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in HYPE
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.