Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
To
|
Amount
|
||
|---|---|---|---|---|---|---|---|
| Grant Role | 985417 | 95 days ago | 0 ETH |
Loading...
Loading
Loading...
Loading
Contract Name:
TriggerableWithdrawalsGateway
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 200 runs
Other Settings:
istanbul EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-FileCopyrightText: 2025 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.9; import {AccessControlEnumerable} from "./utils/access/AccessControlEnumerable.sol"; import {ILidoLocator} from "../common/interfaces/ILidoLocator.sol"; import {ExitRequestLimitData, ExitLimitUtilsStorage, ExitLimitUtils} from "./lib/ExitLimitUtils.sol"; import {PausableUntil} from "./utils/PausableUntil.sol"; struct ValidatorData { uint256 stakingModuleId; uint256 nodeOperatorId; bytes pubkey; } interface IWithdrawalVault { function addWithdrawalRequests(bytes[] calldata pubkeys, uint64[] calldata amounts) external payable; function getWithdrawalRequestFee() external view returns (uint256); } interface IStakingRouter { function onValidatorExitTriggered( ValidatorData[] calldata validatorData, uint256 _withdrawalRequestPaidFee, uint256 _exitType ) external; } /** * @title TriggerableWithdrawalsGateway * @notice TriggerableWithdrawalsGateway contract is one entrypoint for all triggerable withdrawal requests (TWRs) in protocol. * This contract is responsible for limiting TWRs, checking ADD_FULL_WITHDRAWAL_REQUEST_ROLE role before it gets to Withdrawal Vault. */ contract TriggerableWithdrawalsGateway is AccessControlEnumerable, PausableUntil { using ExitLimitUtilsStorage for bytes32; using ExitLimitUtils for ExitRequestLimitData; /** * @notice Thrown when an invalid zero value is passed * @param name Name of the argument that was zero */ error ZeroArgument(string name); /** * @notice Thrown when attempting to set the admin address to zero */ error AdminCannotBeZero(); /** * @notice Thrown when exit request has wrong length */ error InvalidRequestsDataLength(); /** * @notice Thrown when a withdrawal fee insufficient * @param feeRequired Amount of fee required to cover withdrawal request * @param passedValue Amount of fee sent to cover withdrawal request */ error InsufficientFee(uint256 feeRequired, uint256 passedValue); /** * @notice Thrown when a withdrawal fee refund failed */ error FeeRefundFailed(); /** * @notice Thrown when remaining exit requests limit is not enough to cover sender requests * @param requestsCount Amount of requests that were sent for processing * @param remainingLimit Amount of requests that still can be processed at current day */ error ExitRequestsLimitExceeded(uint256 requestsCount, uint256 remainingLimit); /** * @notice Emitted when limits configs are set. * @param maxExitRequestsLimit The maximum number of exit requests. * @param exitsPerFrame The number of exits that can be restored per frame. * @param frameDurationInSec The duration of each frame, in seconds, after which `exitsPerFrame` exits can be restored. */ event ExitRequestsLimitSet(uint256 maxExitRequestsLimit, uint256 exitsPerFrame, uint256 frameDurationInSec); bytes32 public constant PAUSE_ROLE = keccak256("PAUSE_ROLE"); bytes32 public constant RESUME_ROLE = keccak256("RESUME_ROLE"); bytes32 public constant ADD_FULL_WITHDRAWAL_REQUEST_ROLE = keccak256("ADD_FULL_WITHDRAWAL_REQUEST_ROLE"); bytes32 public constant TW_EXIT_LIMIT_MANAGER_ROLE = keccak256("TW_EXIT_LIMIT_MANAGER_ROLE"); bytes32 public constant TWR_LIMIT_POSITION = keccak256("lido.TriggerableWithdrawalsGateway.maxExitRequestLimit"); /// Length in bytes of packed triggerable exit request uint256 internal constant PUBLIC_KEY_LENGTH = 48; uint256 public constant VERSION = 1; ILidoLocator internal immutable LOCATOR; /// @dev Ensures the contract’s ETH balance is unchanged. modifier preservesEthBalance() { uint256 balanceBeforeCall = address(this).balance - msg.value; _; assert(address(this).balance == balanceBeforeCall); } constructor( address admin, address lidoLocator, uint256 maxExitRequestsLimit, uint256 exitsPerFrame, uint256 frameDurationInSec ) { if (admin == address(0)) revert AdminCannotBeZero(); LOCATOR = ILidoLocator(lidoLocator); _setupRole(DEFAULT_ADMIN_ROLE, admin); _setExitRequestLimit(maxExitRequestsLimit, exitsPerFrame, frameDurationInSec); } /** * @dev Resumes the triggerable withdrawals requests. * @notice Reverts if: * - The contract is not paused. * - The sender does not have the `RESUME_ROLE`. */ function resume() external onlyRole(RESUME_ROLE) { _resume(); } /** * @notice Pauses the triggerable withdrawals requests placement for a specified duration. * @param _duration The pause duration in seconds (use `PAUSE_INFINITELY` for unlimited). * @dev Reverts if: * - The contract is already paused. * - The sender does not have the `PAUSE_ROLE`. * - A zero duration is passed. */ function pauseFor(uint256 _duration) external onlyRole(PAUSE_ROLE) { _pauseFor(_duration); } /** * @notice Pauses the triggerable withdrawals requests placement until a specified timestamp. * @param _pauseUntilInclusive The last second to pause until (inclusive). * @dev Reverts if: * - The timestamp is in the past. * - The sender does not have the `PAUSE_ROLE`. * - The contract is already paused. */ function pauseUntil(uint256 _pauseUntilInclusive) external onlyRole(PAUSE_ROLE) { _pauseUntil(_pauseUntilInclusive); } /** * @dev Submits Triggerable Withdrawal Requests to the Withdrawal Vault as full withdrawal requests * for the specified validator public keys. * * @param validatorsData An array of `ValidatorData` structs, each representing a validator * for which a withdrawal request will be submitted. Each entry includes: * - `stakingModuleId`: ID of the staking module. * - `nodeOperatorId`: ID of the node operator. * - `pubkey`: Validator public key, 48 bytes length. * @param refundRecipient The address that will receive any excess ETH sent for fees. * @param exitType A parameter indicating the type of exit, passed to the Staking Module. * * @notice Reverts if: * - The caller does not have the `ADD_FULL_WITHDRAWAL_REQUEST_ROLE` * - The total fee value sent is insufficient to cover all provided TW requests. * - There is not enough limit quota left in the current frame to process all requests. */ function triggerFullWithdrawals( ValidatorData[] calldata validatorsData, address refundRecipient, uint256 exitType ) external payable onlyRole(ADD_FULL_WITHDRAWAL_REQUEST_ROLE) preservesEthBalance whenResumed { if (msg.value == 0) revert ZeroArgument("msg.value"); uint256 requestsCount = validatorsData.length; if (requestsCount == 0) revert ZeroArgument("validatorsData"); _consumeExitRequestLimit(requestsCount); IWithdrawalVault withdrawalVault = IWithdrawalVault(LOCATOR.withdrawalVault()); uint256 fee = withdrawalVault.getWithdrawalRequestFee(); uint256 totalFee = requestsCount * fee; uint256 refund = _checkFee(totalFee); bytes[] memory pubkeys = new bytes[](requestsCount); for (uint256 i = 0; i < requestsCount; ++i) { pubkeys[i] = validatorsData[i].pubkey; } withdrawalVault.addWithdrawalRequests{value: totalFee}(pubkeys, new uint64[](requestsCount)); _notifyStakingModules(validatorsData, fee, exitType); _refundFee(refund, refundRecipient); } /** * @notice Sets the maximum exit request limit and the frame during which a portion of the limit can be restored. * @param maxExitRequestsLimit The maximum number of exit requests. * @param exitsPerFrame The number of exits that can be restored per frame. * @param frameDurationInSec The duration of each frame, in seconds, after which `exitsPerFrame` exits can be restored. */ function setExitRequestLimit( uint256 maxExitRequestsLimit, uint256 exitsPerFrame, uint256 frameDurationInSec ) external onlyRole(TW_EXIT_LIMIT_MANAGER_ROLE) { _setExitRequestLimit(maxExitRequestsLimit, exitsPerFrame, frameDurationInSec); } /** * @notice Returns information about current limits data * @return maxExitRequestsLimit Maximum exit requests limit * @return exitsPerFrame The number of exits that can be restored per frame. * @return frameDurationInSec The duration of each frame, in seconds, after which `exitsPerFrame` exits can be restored. * @return prevExitRequestsLimit Limit left after previous requests * @return currentExitRequestsLimit Current exit requests limit */ function getExitRequestLimitFullInfo() external view returns ( uint256 maxExitRequestsLimit, uint256 exitsPerFrame, uint256 frameDurationInSec, uint256 prevExitRequestsLimit, uint256 currentExitRequestsLimit ) { ExitRequestLimitData memory exitRequestLimitData = TWR_LIMIT_POSITION.getStorageExitRequestLimit(); maxExitRequestsLimit = exitRequestLimitData.maxExitRequestsLimit; exitsPerFrame = exitRequestLimitData.exitsPerFrame; frameDurationInSec = exitRequestLimitData.frameDurationInSec; prevExitRequestsLimit = exitRequestLimitData.prevExitRequestsLimit; currentExitRequestsLimit = exitRequestLimitData.isExitLimitSet() ? exitRequestLimitData.calculateCurrentExitLimit(_getTimestamp()) : type(uint256).max; } /// Internal functions function _checkFee(uint256 fee) internal returns (uint256 refund) { if (msg.value < fee) { revert InsufficientFee(fee, msg.value); } unchecked { refund = msg.value - fee; } } function _notifyStakingModules( ValidatorData[] calldata validatorsData, uint256 withdrawalRequestPaidFee, uint256 exitType ) internal { IStakingRouter stakingRouter = IStakingRouter(LOCATOR.stakingRouter()); stakingRouter.onValidatorExitTriggered(validatorsData, withdrawalRequestPaidFee, exitType); } function _refundFee(uint256 refund, address recipient) internal { if (refund > 0) { // If the refund recipient is not set, use the sender as the refund recipient if (recipient == address(0)) { recipient = msg.sender; } (bool success, ) = recipient.call{value: refund}(""); if (!success) { revert FeeRefundFailed(); } } } function _getTimestamp() internal view virtual returns (uint256) { return block.timestamp; // solhint-disable-line not-rely-on-time } function _setExitRequestLimit( uint256 maxExitRequestsLimit, uint256 exitsPerFrame, uint256 frameDurationInSec ) internal { uint256 timestamp = _getTimestamp(); TWR_LIMIT_POSITION.setStorageExitRequestLimit( TWR_LIMIT_POSITION.getStorageExitRequestLimit().setExitLimits( maxExitRequestsLimit, exitsPerFrame, frameDurationInSec, timestamp ) ); emit ExitRequestsLimitSet(maxExitRequestsLimit, exitsPerFrame, frameDurationInSec); } function _consumeExitRequestLimit(uint256 requestsCount) internal { ExitRequestLimitData memory twrLimitData = TWR_LIMIT_POSITION.getStorageExitRequestLimit(); if (!twrLimitData.isExitLimitSet()) { return; } uint256 limit = twrLimitData.calculateCurrentExitLimit(_getTimestamp()); if (limit < requestsCount) { revert ExitRequestsLimitExceeded(requestsCount, limit); } TWR_LIMIT_POSITION.setStorageExitRequestLimit( twrLimitData.updatePrevExitLimit(limit - requestsCount, _getTimestamp()) ); } }
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
pragma solidity ^0.8.0;
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
/**
* @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.
*
* _Available since v3.1._
*/
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, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
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 `account`.
*/
function renounceRole(bytes32 role, address account) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol)
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
/**
* @dev External interface of AccessControlEnumerable declared to support ERC165 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 v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 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);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* 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[EIP 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);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)
pragma solidity ^0.8.0;
/**
* @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.
*
* ```
* 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.
*/
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 of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping(bytes32 => uint256) _indexes;
}
/**
* @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._indexes[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 read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 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 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
if (lastIndex != toDeleteIndex) {
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[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._indexes[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) {
return _values(set._inner);
}
// 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 {
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 on 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 {
result := store
}
return result;
}
}// SPDX-FileCopyrightText: 2025 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.9; struct ExitRequestLimitData { uint32 maxExitRequestsLimit; // Maximum limit uint32 prevExitRequestsLimit; // Limit left after previous requests uint32 prevTimestamp; // Timestamp of the last update uint32 frameDurationInSec; // Seconds that should pass to restore part of exits uint32 exitsPerFrame; // Restored exits per frame } library ExitLimitUtilsStorage { struct DataStorage { ExitRequestLimitData _exitRequestLimitData; } function getStorageExitRequestLimit(bytes32 _position) internal view returns (ExitRequestLimitData memory) { return _getDataStorage(_position)._exitRequestLimitData; } function setStorageExitRequestLimit(bytes32 _position, ExitRequestLimitData memory _data) internal { _getDataStorage(_position)._exitRequestLimitData = _data; } function _getDataStorage(bytes32 _position) private pure returns (DataStorage storage $) { assembly { $.slot := _position } } } library ExitLimitUtils { /// @notice Error when new value for remaining limit exceeds maximum limit. error LimitExceeded(); /// @notice Error when max exit request limit exceeds uint32 max. error TooLargeMaxExitRequestsLimit(); /// @notice Error when frame duration exceeds uint32 max. error TooLargeFrameDuration(); /// @notice Error when exits per frame exceed the maximum exit request limit. error TooLargeExitsPerFrame(); /// @notice Error when frame duration is zero. error ZeroFrameDuration(); function calculateCurrentExitLimit( ExitRequestLimitData memory _data, uint256 timestamp ) internal pure returns (uint256 currentLimit) { uint256 secondsPassed = timestamp - _data.prevTimestamp; if (secondsPassed < _data.frameDurationInSec || _data.exitsPerFrame == 0) { return _data.prevExitRequestsLimit; } uint256 framesPassed = secondsPassed / _data.frameDurationInSec; uint256 restoredLimit = framesPassed * _data.exitsPerFrame; uint256 newLimit = _data.prevExitRequestsLimit + restoredLimit; if (newLimit > _data.maxExitRequestsLimit) { newLimit = _data.maxExitRequestsLimit; } return newLimit; } function updatePrevExitLimit( ExitRequestLimitData memory _data, uint256 newExitRequestLimit, uint256 timestamp ) internal pure returns (ExitRequestLimitData memory) { if (_data.maxExitRequestsLimit < newExitRequestLimit) revert LimitExceeded(); uint256 secondsPassed = timestamp - _data.prevTimestamp; uint256 framesPassed = secondsPassed / _data.frameDurationInSec; uint32 passedTime = uint32(framesPassed) * _data.frameDurationInSec; _data.prevExitRequestsLimit = uint32(newExitRequestLimit); _data.prevTimestamp += passedTime; return _data; } function setExitLimits( ExitRequestLimitData memory _data, uint256 maxExitRequestsLimit, uint256 exitsPerFrame, uint256 frameDurationInSec, uint256 timestamp ) internal pure returns (ExitRequestLimitData memory) { if (maxExitRequestsLimit > type(uint32).max) revert TooLargeMaxExitRequestsLimit(); if (frameDurationInSec > type(uint32).max) revert TooLargeFrameDuration(); if (exitsPerFrame > maxExitRequestsLimit) revert TooLargeExitsPerFrame(); if (frameDurationInSec == 0) revert ZeroFrameDuration(); _data.exitsPerFrame = uint32(exitsPerFrame); _data.frameDurationInSec = uint32(frameDurationInSec); if ( // new maxExitRequestsLimit is smaller than prev remaining limit maxExitRequestsLimit < _data.prevExitRequestsLimit || // previously exits were unlimited _data.maxExitRequestsLimit == 0 ) { _data.prevExitRequestsLimit = uint32(maxExitRequestsLimit); } _data.maxExitRequestsLimit = uint32(maxExitRequestsLimit); _data.prevTimestamp = uint32(timestamp); return _data; } function isExitLimitSet(ExitRequestLimitData memory _data) internal pure returns (bool) { return _data.maxExitRequestsLimit != 0; } }
/*
* SPDX-License-Identifier: MIT
*/
pragma solidity 0.8.9;
/**
* @notice Aragon Unstructured Storage library
*/
library UnstructuredStorage {
function getStorageBool(bytes32 position) internal view returns (bool data) {
assembly { data := sload(position) }
}
function getStorageAddress(bytes32 position) internal view returns (address data) {
assembly { data := sload(position) }
}
function getStorageBytes32(bytes32 position) internal view returns (bytes32 data) {
assembly { data := sload(position) }
}
function getStorageUint256(bytes32 position) internal view returns (uint256 data) {
assembly { data := sload(position) }
}
function setStorageBool(bytes32 position, bool data) internal {
assembly { sstore(position, data) }
}
function setStorageAddress(bytes32 position, address data) internal {
assembly { sstore(position, data) }
}
function setStorageBytes32(bytes32 position, bytes32 data) internal {
assembly { sstore(position, data) }
}
function setStorageUint256(bytes32 position, uint256 data) internal {
assembly { sstore(position, data) }
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/AccessControl.sol)
//
// A modified AccessControl contract using unstructured storage. Copied from tree:
// https://github.com/OpenZeppelin/openzeppelin-contracts/tree/6bd6b76/contracts/access
//
/* See contracts/COMPILERS.md */
pragma solidity 0.8.9;
import "@openzeppelin/contracts-v4.4/access/IAccessControl.sol";
import "@openzeppelin/contracts-v4.4/utils/Context.sol";
import "@openzeppelin/contracts-v4.4/utils/Strings.sol";
import "@openzeppelin/contracts-v4.4/utils/introspection/ERC165.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:
*
* ```
* 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}:
*
* ```
* 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.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
/// @dev Storage slot: mapping(bytes32 => RoleData) _roles
bytes32 private constant ROLES_POSITION = keccak256("openzeppelin.AccessControl._roles");
function _storageRoles() private pure returns (mapping(bytes32 => RoleData) storage _roles) {
bytes32 position = ROLES_POSITION;
assembly { _roles.slot := position }
}
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with a standardized message including the required role.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*
* _Available since v4.1._
*/
modifier onlyRole(bytes32 role) {
_checkRole(role, _msgSender());
_;
}
/**
* @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 override returns (bool) {
return _storageRoles()[role].members[account];
}
/**
* @dev Revert with a standard message if `account` is missing `role`.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*/
function _checkRole(bytes32 role, address account) internal view {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(uint160(account), 20),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
/**
* @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 override returns (bytes32) {
return _storageRoles()[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.
*/
function grantRole(bytes32 role, address account) public virtual override 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.
*/
function revokeRole(bytes32 role, address account) public virtual override 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 `account`.
*/
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*
* NOTE: This function is deprecated in favor of {_grantRole}.
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_storageRoles()[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Grants `role` to `account`.
*
* Internal function without access restriction.
*/
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_storageRoles()[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
/**
* @dev Revokes `role` from `account`.
*
* Internal function without access restriction.
*/
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_storageRoles()[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/AccessControlEnumerable.sol)
//
// A modified AccessControlEnumerable contract using unstructured storage. Copied from tree:
// https://github.com/OpenZeppelin/openzeppelin-contracts/tree/6bd6b76/contracts/access
//
/* See contracts/COMPILERS.md */
pragma solidity 0.8.9;
import "@openzeppelin/contracts-v4.4/access/IAccessControlEnumerable.sol";
import "@openzeppelin/contracts-v4.4/utils/structs/EnumerableSet.sol";
import "./AccessControl.sol";
/**
* @dev Extension of {AccessControl} that allows enumerating the members of each role.
*/
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
using EnumerableSet for EnumerableSet.AddressSet;
/// @dev Storage slot: mapping(bytes32 => EnumerableSet.AddressSet) _roleMembers
bytes32 private constant ROLE_MEMBERS_POSITION = keccak256("openzeppelin.AccessControlEnumerable._roleMembers");
function _storageRoleMembers() private pure returns (
mapping(bytes32 => EnumerableSet.AddressSet) storage _roleMembers
) {
bytes32 position = ROLE_MEMBERS_POSITION;
assembly { _roleMembers.slot := position }
}
/**
* @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 override returns (address) {
return _storageRoleMembers()[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 override returns (uint256) {
return _storageRoleMembers()[role].length();
}
/**
* @dev Overload {_grantRole} to track enumerable memberships
*/
function _grantRole(bytes32 role, address account) internal virtual override {
super._grantRole(role, account);
_storageRoleMembers()[role].add(account);
}
/**
* @dev Overload {_revokeRole} to track enumerable memberships
*/
function _revokeRole(bytes32 role, address account) internal virtual override {
super._revokeRole(role, account);
_storageRoleMembers()[role].remove(account);
}
}// SPDX-FileCopyrightText: 2023 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 pragma solidity 0.8.9; import "../lib/UnstructuredStorage.sol"; contract PausableUntil { using UnstructuredStorage for bytes32; /// Contract resume/pause control storage slot bytes32 internal constant RESUME_SINCE_TIMESTAMP_POSITION = keccak256("lido.PausableUntil.resumeSinceTimestamp"); /// Special value for the infinite pause uint256 public constant PAUSE_INFINITELY = type(uint256).max; /// @notice Emitted when paused by the `pauseFor` or `pauseUntil` call event Paused(uint256 duration); /// @notice Emitted when resumed by the `resume` call event Resumed(); error ZeroPauseDuration(); error PausedExpected(); error ResumedExpected(); error PauseUntilMustBeInFuture(); /// @notice Reverts when resumed modifier whenPaused() { _checkPaused(); _; } /// @notice Reverts when paused modifier whenResumed() { _checkResumed(); _; } function _checkPaused() internal view { if (!isPaused()) { revert PausedExpected(); } } function _checkResumed() internal view { if (isPaused()) { revert ResumedExpected(); } } /// @notice Returns whether the contract is paused function isPaused() public view returns (bool) { return block.timestamp < RESUME_SINCE_TIMESTAMP_POSITION.getStorageUint256(); } /// @notice Returns one of: /// - PAUSE_INFINITELY if paused infinitely returns /// - first second when get contract get resumed if paused for specific duration /// - some timestamp in past if not paused function getResumeSinceTimestamp() external view returns (uint256) { return RESUME_SINCE_TIMESTAMP_POSITION.getStorageUint256(); } function _resume() internal { _checkPaused(); RESUME_SINCE_TIMESTAMP_POSITION.setStorageUint256(block.timestamp); emit Resumed(); } function _pauseFor(uint256 _duration) internal { _checkResumed(); if (_duration == 0) revert ZeroPauseDuration(); uint256 resumeSince; if (_duration == PAUSE_INFINITELY) { resumeSince = PAUSE_INFINITELY; } else { resumeSince = block.timestamp + _duration; } _setPausedState(resumeSince); } function _pauseUntil(uint256 _pauseUntilInclusive) internal { _checkResumed(); if (_pauseUntilInclusive < block.timestamp) revert PauseUntilMustBeInFuture(); uint256 resumeSince; if (_pauseUntilInclusive != PAUSE_INFINITELY) { resumeSince = _pauseUntilInclusive + 1; } else { resumeSince = PAUSE_INFINITELY; } _setPausedState(resumeSince); } function _setPausedState(uint256 _resumeSince) internal { RESUME_SINCE_TIMESTAMP_POSITION.setStorageUint256(_resumeSince); if (_resumeSince == PAUSE_INFINITELY) { emit Paused(PAUSE_INFINITELY); } else { emit Paused(_resumeSince - block.timestamp); } } }
// SPDX-FileCopyrightText: 2025 Lido <[email protected]> // SPDX-License-Identifier: GPL-3.0 // See contracts/COMPILERS.md // solhint-disable-next-line lido/fixed-compiler-version pragma solidity >=0.4.24 <0.9.0; interface ILidoLocator { function accountingOracle() external view returns(address); function depositSecurityModule() external view returns(address); function elRewardsVault() external view returns(address); function lido() external view returns(address); function oracleReportSanityChecker() external view returns(address); function burner() external view returns(address); function stakingRouter() external view returns(address); function treasury() external view returns(address); function validatorsExitBusOracle() external view returns(address); function withdrawalQueue() external view returns(address); function withdrawalVault() external view returns(address); function postTokenRebaseReceiver() external view returns(address); function oracleDaemonConfig() external view returns(address); function validatorExitDelayVerifier() external view returns (address); function triggerableWithdrawalsGateway() external view returns (address); function accounting() external view returns (address); function predepositGuarantee() external view returns (address); function wstETH() external view returns (address); function vaultHub() external view returns (address); function vaultFactory() external view returns (address); function lazyOracle() external view returns (address); function operatorGrid() external view returns (address); /// @notice Returns core Lido protocol component addresses in a single call /// @dev This function provides a gas-efficient way to fetch multiple component addresses in a single call function coreComponents() external view returns( address elRewardsVault, address oracleReportSanityChecker, address stakingRouter, address treasury, address withdrawalQueue, address withdrawalVault ); /// @notice Returns addresses of components involved in processing oracle reports in the Lido contract /// @dev This function provides a gas-efficient way to fetch multiple component addresses in a single call function oracleReportComponents() external view returns( address accountingOracle, address oracleReportSanityChecker, address burner, address withdrawalQueue, address postTokenRebaseReceiver, address stakingRouter, address vaultHub ); }
{
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "istanbul",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract ABI
API[{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"lidoLocator","type":"address"},{"internalType":"uint256","name":"maxExitRequestsLimit","type":"uint256"},{"internalType":"uint256","name":"exitsPerFrame","type":"uint256"},{"internalType":"uint256","name":"frameDurationInSec","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AdminCannotBeZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"requestsCount","type":"uint256"},{"internalType":"uint256","name":"remainingLimit","type":"uint256"}],"name":"ExitRequestsLimitExceeded","type":"error"},{"inputs":[],"name":"FeeRefundFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"feeRequired","type":"uint256"},{"internalType":"uint256","name":"passedValue","type":"uint256"}],"name":"InsufficientFee","type":"error"},{"inputs":[],"name":"InvalidRequestsDataLength","type":"error"},{"inputs":[],"name":"LimitExceeded","type":"error"},{"inputs":[],"name":"PauseUntilMustBeInFuture","type":"error"},{"inputs":[],"name":"PausedExpected","type":"error"},{"inputs":[],"name":"ResumedExpected","type":"error"},{"inputs":[],"name":"TooLargeExitsPerFrame","type":"error"},{"inputs":[],"name":"TooLargeFrameDuration","type":"error"},{"inputs":[],"name":"TooLargeMaxExitRequestsLimit","type":"error"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"ZeroArgument","type":"error"},{"inputs":[],"name":"ZeroFrameDuration","type":"error"},{"inputs":[],"name":"ZeroPauseDuration","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxExitRequestsLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"exitsPerFrame","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"frameDurationInSec","type":"uint256"}],"name":"ExitRequestsLimitSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[],"name":"Resumed","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"},{"inputs":[],"name":"ADD_FULL_WITHDRAWAL_REQUEST_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_INFINITELY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESUME_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TWR_LIMIT_POSITION","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TW_EXIT_LIMIT_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExitRequestLimitFullInfo","outputs":[{"internalType":"uint256","name":"maxExitRequestsLimit","type":"uint256"},{"internalType":"uint256","name":"exitsPerFrame","type":"uint256"},{"internalType":"uint256","name":"frameDurationInSec","type":"uint256"},{"internalType":"uint256","name":"prevExitRequestsLimit","type":"uint256"},{"internalType":"uint256","name":"currentExitRequestsLimit","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getResumeSinceTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","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":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_duration","type":"uint256"}],"name":"pauseFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pauseUntilInclusive","type":"uint256"}],"name":"pauseUntil","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resume","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":"uint256","name":"maxExitRequestsLimit","type":"uint256"},{"internalType":"uint256","name":"exitsPerFrame","type":"uint256"},{"internalType":"uint256","name":"frameDurationInSec","type":"uint256"}],"name":"setExitRequestLimit","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":[{"components":[{"internalType":"uint256","name":"stakingModuleId","type":"uint256"},{"internalType":"uint256","name":"nodeOperatorId","type":"uint256"},{"internalType":"bytes","name":"pubkey","type":"bytes"}],"internalType":"struct ValidatorData[]","name":"validatorsData","type":"tuple[]"},{"internalType":"address","name":"refundRecipient","type":"address"},{"internalType":"uint256","name":"exitType","type":"uint256"}],"name":"triggerFullWithdrawals","outputs":[],"stateMutability":"payable","type":"function"}]Contract Creation Code
60a06040523480156200001157600080fd5b506040516200255538038062002555833981016040819052620000349162000528565b6001600160a01b0385166200005c57604051636b35b1b760e01b815260040160405180910390fd5b6001600160a01b038416608052620000766000866200008e565b620000838383836200009e565b50505050506200057b565b6200009a828262000156565b5050565b60004290506200010f620000eb85858585620000d460008051602062002535833981519152620001b760201b62000b771760201c565b6200024760201b62000bf91790949392919060201c565b600080516020620025358339815191526200035a60201b62000d061790919060201c565b60408051858152602081018590529081018390527f3119d910326e0f179e121df55f23f45b8a5022ff10c73c02aabf2b48ae36070a9060600160405180910390a150505050565b6200016d8282620003f760201b62000d9c1760201c565b620001b2817f8f8c450dae5029cd48cd91dd9db65da48fb742893edfc7941250f6721d93cbbe6000858152602091825260409020919062000e1262000499821b17901c565b505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152816040805160a081018252915463ffffffff80821684526401000000008204811660208501526801000000000000000082048116928401929092526c01000000000000000000000000810482166060840152600160801b900416608082015292915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915263ffffffff8511156200029857604051635752823560e11b815260040160405180910390fd5b63ffffffff831115620002be5760405163bbdd2da360e01b815260040160405180910390fd5b84841115620002e05760405163528f486360e01b815260040160405180910390fd5b82620002ff57604051636765a75d60e01b815260040160405180910390fd5b63ffffffff808516608088015283811660608801526020870151168510806200032d5750855163ffffffff16155b15620003405763ffffffff851660208701525b5063ffffffff938416855290921660408401525090919050565b8051825460208301516040840151606085015160809095015163ffffffff9485166001600160401b0319909416939093176401000000009285169290920291909117600160401b600160801b031916680100000000000000009184169190910263ffffffff60601b1916176c01000000000000000000000000938316939093029290921763ffffffff60801b1916600160801b9190921602179055565b600082815260008051602062002515833981519152602090815260408083206001600160a01b038516845290915290205460ff166200009a57600082815260008051602062002515833981519152602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b6000620004b0836001600160a01b038416620004b9565b90505b92915050565b60008181526001830160205260408120546200050257508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004b3565b506000620004b3565b80516001600160a01b03811681146200052357600080fd5b919050565b600080600080600060a086880312156200054157600080fd5b6200054c866200050b565b94506200055c602087016200050b565b6040870151606088015160809098015196999198509695945092505050565b608051611f776200059e600039600081816105dc0152610ffb0152611f776000f3fe60806040526004361061014b5760003560e01c80639010d07c116100b6578063b187bd261161006f578063b187bd26146103e7578063b6b764b2146103fc578063ca15c87314610439578063d547741f14610459578063f3f449c714610479578063ffa1ad741461049957600080fd5b80639010d07c1461031057806391d1485414610348578063a0cbdf1414610368578063a217fddf1461039c578063a302ee38146103b1578063abe9cfc8146103c757600080fd5b80632f2ff15d116101085780632f2ff15d1461024557806336568abe14610265578063389ed2671461028557806356254a97146102b9578063589ff76c146102d957806376b0023e146102ee57600080fd5b806301ffc9a714610150578063046f7da214610185578063138b1b151461019c578063248a9ca3146101af5780632d44866b146101dd5780632de03aa114610211575b600080fd5b34801561015c57600080fd5b5061017061016b3660046118e9565b6104ae565b60405190151581526020015b60405180910390f35b34801561019157600080fd5b5061019a6104d9565b005b61019a6101aa366004611928565b61050f565b3480156101bb57600080fd5b506101cf6101ca3660046119b4565b6108c6565b60405190815260200161017c565b3480156101e957600080fd5b506101cf7f03c30da9b9e4d4789ac88a294d39a63058ca4a498804c2aa823e381df59d0cf481565b34801561021d57600080fd5b506101cf7f2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c781565b34801561025157600080fd5b5061019a6102603660046119cd565b6108e8565b34801561027157600080fd5b5061019a6102803660046119cd565b61090a565b34801561029157600080fd5b506101cf7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d81565b3480156102c557600080fd5b5061019a6102d43660046119fd565b610988565b3480156102e557600080fd5b506101cf6109c4565b3480156102fa57600080fd5b506101cf600080516020611f2283398151915281565b34801561031c57600080fd5b5061033061032b366004611a29565b6109e1565b6040516001600160a01b03909116815260200161017c565b34801561035457600080fd5b506101706103633660046119cd565b610a0d565b34801561037457600080fd5b506101cf7f15fac8ba7fe8dd5344b88c1915452ce66976f270d1cd793c3b0ab579cecd33c081565b3480156103a857600080fd5b506101cf600081565b3480156103bd57600080fd5b506101cf60001981565b3480156103d357600080fd5b5061019a6103e23660046119b4565b610a45565b3480156103f357600080fd5b50610170610a79565b34801561040857600080fd5b50610411610a98565b604080519586526020860194909452928401919091526060830152608082015260a00161017c565b34801561044557600080fd5b506101cf6104543660046119b4565b610b02565b34801561046557600080fd5b5061019a6104743660046119cd565b610b26565b34801561048557600080fd5b5061019a6104943660046119b4565b610b43565b3480156104a557600080fd5b506101cf600181565b60006001600160e01b03198216635a05180f60e01b14806104d357506104d382610e27565b92915050565b7f2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c76105048133610e5c565b61050c610ec0565b50565b7f15fac8ba7fe8dd5344b88c1915452ce66976f270d1cd793c3b0ab579cecd33c061053a8133610e5c565b60006105463447611a61565b9050610550610f04565b3461058f576040516356e4289360e01b81526020600482015260096024820152686d73672e76616c756560b81b60448201526064015b60405180910390fd5b84806105cf576040516356e4289360e01b815260206004820152600e60248201526d76616c696461746f72734461746160901b6044820152606401610586565b6105d881610f2c565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166369d421486040518163ffffffff1660e01b815260040160206040518083038186803b15801561063357600080fd5b505afa158015610647573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066b9190611a78565b90506000816001600160a01b031663c44e30dc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156106a857600080fd5b505afa1580156106bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e09190611a95565b905060006106ee8285611aae565b905060006106fb82610fc5565b905060008567ffffffffffffffff81111561071857610718611acd565b60405190808252806020026020018201604052801561074b57816020015b60608152602001906001900390816107365790505b50905060005b868110156107ef578c8c8281811061076b5761076b611ae3565b905060200281019061077d9190611af9565b61078b906040810190611b19565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050845185925084915081106107d3576107d3611ae3565b6020026020010181905250806107e890611b67565b9050610751565b50846001600160a01b031663eb3f512a84838967ffffffffffffffff81111561081a5761081a611acd565b604051908082528060200260200182016040528015610843578160200160208202803683370190505b506040518463ffffffff1660e01b8152600401610861929190611bda565b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b505050505061089f8c8c868c610ff7565b6108a9828b6110f8565b5050505050508047146108be576108be611c7f565b505050505050565b6000908152600080516020611ee2833981519152602052604090206001015490565b6108f1826108c6565b6108fb8133610e5c565b6109058383611183565b505050565b6001600160a01b038116331461097a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610586565b61098482826111b2565b5050565b7f03c30da9b9e4d4789ac88a294d39a63058ca4a498804c2aa823e381df59d0cf46109b38133610e5c565b6109be8484846111e1565b50505050565b60006109dc600080516020611f028339815191525490565b905090565b6000828152600080516020611ec283398151915260205260408120610a069083611253565b9392505050565b6000918252600080516020611ee2833981519152602090815260408084206001600160a01b0393909316845291905290205460ff1690565b7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d610a708133610e5c565b6109848261125f565b6000610a91600080516020611f028339815191525490565b4210905090565b600080600080600080610ab8600080516020611f22833981519152610b77565b805160808201516060830151602084015163ffffffff9384169a50918316985082169650169350905085610aee57600019610af8565b610af881426112b3565b9150509091929394565b6000818152600080516020611ec2833981519152602052604081206104d390611377565b610b2f826108c6565b610b398133610e5c565b61090583836111b2565b7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d610b6e8133610e5c565b61098482611381565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152816040805160a081018252915463ffffffff8082168452640100000000820481166020850152600160401b8204811692840192909252600160601b810482166060840152600160801b900416608082015292915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915263ffffffff851115610c4957604051635752823560e11b815260040160405180910390fd5b63ffffffff831115610c6e5760405163bbdd2da360e01b815260040160405180910390fd5b84841115610c8f5760405163528f486360e01b815260040160405180910390fd5b82610cad57604051636765a75d60e01b815260040160405180910390fd5b63ffffffff80851660808801528381166060880152602087015116851080610cda5750855163ffffffff16155b15610cec5763ffffffff851660208701525b5063ffffffff938416855290921660408401525090919050565b8051825460208301516040840151606085015160809095015163ffffffff94851667ffffffffffffffff199094169390931764010000000092851692909202919091176fffffffffffffffff00000000000000001916600160401b9184169190910263ffffffff60601b191617600160601b938316939093029290921763ffffffff60801b1916600160801b9190921602179055565b610da68282610a0d565b610984576000828152600080516020611ee2833981519152602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b6000610a06836001600160a01b0384166113d1565b60006001600160e01b03198216637965db0b60e01b14806104d357506301ffc9a760e01b6001600160e01b03198316146104d3565b610e668282610a0d565b61098457610e7e816001600160a01b03166014611420565b610e89836020611420565b604051602001610e9a929190611c95565b60408051601f198184030181529082905262461bcd60e51b825261058691600401611d0a565b610ec86115bc565b42600080516020611f02833981519152556040517f62451d457bc659158be6e6247f56ec1df424a5c7597f71c20c2bc44e0965c8f990600090a1565b610f0c610a79565b15610f2a57604051630286f07360e31b815260040160405180910390fd5b565b6000610f45600080516020611f22833981519152610b77565b9050610f57815163ffffffff16151590565b610f5f575050565b6000610f6b82426112b3565b905082811015610f985760405163106865a560e31b81526004810184905260248101829052604401610586565b610905610fb0610fa88584611a61565b8490426115e1565b600080516020611f2283398151915290610d06565b600081341015610ff15760405163a458261b60e01b815260048101839052346024820152604401610586565b50340390565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663ef6c064c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561105257600080fd5b505afa158015611066573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108a9190611a78565b604051637141658360e01b81529091506001600160a01b038216906371416583906110bf908890889088908890600401611d1d565b600060405180830381600087803b1580156110d957600080fd5b505af11580156110ed573d6000803e3d6000fd5b505050505050505050565b8115610984576001600160a01b03811661110f5750335b6000816001600160a01b03168360405160006040518083038185875af1925050503d806000811461115c576040519150601f19603f3d011682016040523d82523d6000602084013e611161565b606091505b505090508061090557604051637f832e9560e01b815260040160405180910390fd5b61118d8282610d9c565b6000828152600080516020611ec2833981519152602052604090206109059082610e12565b6111bc82826116b0565b6000828152600080516020611ec2833981519152602052604090206109059082611724565b4261120c610fb085858585611203600080516020611f22833981519152610b77565b93929190610bf9565b60408051858152602081018590529081018390527f3119d910326e0f179e121df55f23f45b8a5022ff10c73c02aabf2b48ae36070a9060600160405180910390a150505050565b6000610a068383611739565b611267610f04565b42811015611288576040516339e2ec5360e11b815260040160405180910390fd5b600060001982146112a55761129e826001611e06565b90506112aa565b506000195b61098481611763565b600080836040015163ffffffff16836112cc9190611a61565b9050836060015163ffffffff168110806112ee5750608084015163ffffffff16155b15611305575050602082015163ffffffff166104d3565b6000846060015163ffffffff168261131d9190611e1e565b90506000856080015163ffffffff16826113379190611aae565b9050600081876020015163ffffffff166113519190611e06565b875190915063ffffffff1681111561136d5750855163ffffffff165b9695505050505050565b60006104d3825490565b611389610f04565b806113a75760405163ad58bfc760e01b815260040160405180910390fd5b60006000198214156113bc57506000196112aa565b6113c68242611e06565b905061098481611763565b6000818152600183016020526040812054611418575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104d3565b5060006104d3565b6060600061142f836002611aae565b61143a906002611e06565b67ffffffffffffffff81111561145257611452611acd565b6040519080825280601f01601f19166020018201604052801561147c576020820181803683370190505b509050600360fc1b8160008151811061149757611497611ae3565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106114c6576114c6611ae3565b60200101906001600160f81b031916908160001a90535060006114ea846002611aae565b6114f5906001611e06565b90505b600181111561156d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061152957611529611ae3565b1a60f81b82828151811061153f5761153f611ae3565b60200101906001600160f81b031916908160001a90535060049490941c9361156681611e40565b90506114f8565b508315610a065760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610586565b6115c4610a79565b610f2a5760405163b047186b60e01b815260040160405180910390fd5b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152835163ffffffff1683111561163457604051631930e3c960e11b815260040160405180910390fd5b6000846040015163ffffffff168361164c9190611a61565b90506000856060015163ffffffff16826116669190611e1e565b9050600086606001518261167a9190611e57565b63ffffffff87166020890152604088018051919250829161169c908390611e83565b63ffffffff16905250959695505050505050565b6116ba8282610a0d565b15610984576000828152600080516020611ee2833981519152602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610a06836001600160a01b0384166117f6565b600082600001828154811061175057611750611ae3565b9060005260206000200154905092915050565b61177a600080516020611f02833981519152829055565b6000198114156117bd5760405160001981527f32fb7c9891bc4f963c7de9f1186d2a7755c7d6e9f4604dabe1d8bb3027c2f49e906020015b60405180910390a150565b7f32fb7c9891bc4f963c7de9f1186d2a7755c7d6e9f4604dabe1d8bb3027c2f49e6117e84283611a61565b6040519081526020016117b2565b600081815260018301602052604081205480156118df57600061181a600183611a61565b855490915060009061182e90600190611a61565b905081811461189357600086600001828154811061184e5761184e611ae3565b906000526020600020015490508087600001848154811061187157611871611ae3565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118a4576118a4611eab565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104d3565b60009150506104d3565b6000602082840312156118fb57600080fd5b81356001600160e01b031981168114610a0657600080fd5b6001600160a01b038116811461050c57600080fd5b6000806000806060858703121561193e57600080fd5b843567ffffffffffffffff8082111561195657600080fd5b818701915087601f83011261196a57600080fd5b81358181111561197957600080fd5b8860208260051b850101111561198e57600080fd5b602092830196509450508501356119a481611913565b9396929550929360400135925050565b6000602082840312156119c657600080fd5b5035919050565b600080604083850312156119e057600080fd5b8235915060208301356119f281611913565b809150509250929050565b600080600060608486031215611a1257600080fd5b505081359360208301359350604090920135919050565b60008060408385031215611a3c57600080fd5b50508035926020909101359150565b634e487b7160e01b600052601160045260246000fd5b600082821015611a7357611a73611a4b565b500390565b600060208284031215611a8a57600080fd5b8151610a0681611913565b600060208284031215611aa757600080fd5b5051919050565b6000816000190483118215151615611ac857611ac8611a4b565b500290565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112611b0f57600080fd5b9190910192915050565b6000808335601e19843603018112611b3057600080fd5b83018035915067ffffffffffffffff821115611b4b57600080fd5b602001915036819003821315611b6057600080fd5b9250929050565b6000600019821415611b7b57611b7b611a4b565b5060010190565b60005b83811015611b9d578181015183820152602001611b85565b838111156109be5750506000910152565b60008151808452611bc6816020860160208601611b82565b601f01601f19169290920160200192915050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015611c3157605f19888703018552611c1f868351611bae565b95509382019390820190600101611c03565b50508584038187015286518085528782019482019350915060005b82811015611c7257845167ffffffffffffffff1684529381019392810192600101611c4c565b5091979650505050505050565b634e487b7160e01b600052600160045260246000fd5b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611ccd816017850160208801611b82565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611cfe816028840160208801611b82565b01602801949350505050565b602081526000610a066020830184611bae565b60608082528181018590526000906080808401600588901b8501820189855b8a811015611dee57878303607f190184528135368d9003605e19018112611d6257600080fd5b8c01803584526020808201358186015260408083013536849003601e19018112611d8b57600080fd5b8301803567ffffffffffffffff811115611da457600080fd5b803603851315611db357600080fd5b8a83890152808b890152808483018b8a013760008882018b015297830197601f01601f19169096018801955050929092019150600101611d3c565b50506020860197909752505050506040015292915050565b60008219821115611e1957611e19611a4b565b500190565b600082611e3b57634e487b7160e01b600052601260045260246000fd5b500490565b600081611e4f57611e4f611a4b565b506000190190565b600063ffffffff80831681851681830481118215151615611e7a57611e7a611a4b565b02949350505050565b600063ffffffff808316818516808303821115611ea257611ea2611a4b565b01949350505050565b634e487b7160e01b600052603160045260246000fdfe8f8c450dae5029cd48cd91dd9db65da48fb742893edfc7941250f6721d93cbbe9a627a5d4aa7c17f87ff26e3fe9a42c2b6c559e8b41a42282d0ecebb17c0e4d3e8b012900cb200ee5dfc3b895a32791b67d12891b09f117814f167a237783a023a69583d449251314fd68e4e68fe89ca455d27f2701d2fdee1b16c585fc4e2d6a2646970667358221220d5db186c862dafc8c8d035ee0a29a267f14655bc8209a2edf0400781fd8e53f664736f6c634300080900339a627a5d4aa7c17f87ff26e3fe9a42c2b6c559e8b41a42282d0ecebb17c0e4d33a69583d449251314fd68e4e68fe89ca455d27f2701d2fdee1b16c585fc4e2d600000000000000000000000026edb7f0f223a25ee390accccb577f3a31eddfc5000000000000000000000000d7c1b80fa86965b48cca3adccb08e1daea29198000000000000000000000000000000000000000000000000000000000000032c800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000030
Deployed Bytecode
0x60806040526004361061014b5760003560e01c80639010d07c116100b6578063b187bd261161006f578063b187bd26146103e7578063b6b764b2146103fc578063ca15c87314610439578063d547741f14610459578063f3f449c714610479578063ffa1ad741461049957600080fd5b80639010d07c1461031057806391d1485414610348578063a0cbdf1414610368578063a217fddf1461039c578063a302ee38146103b1578063abe9cfc8146103c757600080fd5b80632f2ff15d116101085780632f2ff15d1461024557806336568abe14610265578063389ed2671461028557806356254a97146102b9578063589ff76c146102d957806376b0023e146102ee57600080fd5b806301ffc9a714610150578063046f7da214610185578063138b1b151461019c578063248a9ca3146101af5780632d44866b146101dd5780632de03aa114610211575b600080fd5b34801561015c57600080fd5b5061017061016b3660046118e9565b6104ae565b60405190151581526020015b60405180910390f35b34801561019157600080fd5b5061019a6104d9565b005b61019a6101aa366004611928565b61050f565b3480156101bb57600080fd5b506101cf6101ca3660046119b4565b6108c6565b60405190815260200161017c565b3480156101e957600080fd5b506101cf7f03c30da9b9e4d4789ac88a294d39a63058ca4a498804c2aa823e381df59d0cf481565b34801561021d57600080fd5b506101cf7f2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c781565b34801561025157600080fd5b5061019a6102603660046119cd565b6108e8565b34801561027157600080fd5b5061019a6102803660046119cd565b61090a565b34801561029157600080fd5b506101cf7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d81565b3480156102c557600080fd5b5061019a6102d43660046119fd565b610988565b3480156102e557600080fd5b506101cf6109c4565b3480156102fa57600080fd5b506101cf600080516020611f2283398151915281565b34801561031c57600080fd5b5061033061032b366004611a29565b6109e1565b6040516001600160a01b03909116815260200161017c565b34801561035457600080fd5b506101706103633660046119cd565b610a0d565b34801561037457600080fd5b506101cf7f15fac8ba7fe8dd5344b88c1915452ce66976f270d1cd793c3b0ab579cecd33c081565b3480156103a857600080fd5b506101cf600081565b3480156103bd57600080fd5b506101cf60001981565b3480156103d357600080fd5b5061019a6103e23660046119b4565b610a45565b3480156103f357600080fd5b50610170610a79565b34801561040857600080fd5b50610411610a98565b604080519586526020860194909452928401919091526060830152608082015260a00161017c565b34801561044557600080fd5b506101cf6104543660046119b4565b610b02565b34801561046557600080fd5b5061019a6104743660046119cd565b610b26565b34801561048557600080fd5b5061019a6104943660046119b4565b610b43565b3480156104a557600080fd5b506101cf600181565b60006001600160e01b03198216635a05180f60e01b14806104d357506104d382610e27565b92915050565b7f2fc10cc8ae19568712f7a176fb4978616a610650813c9d05326c34abb62749c76105048133610e5c565b61050c610ec0565b50565b7f15fac8ba7fe8dd5344b88c1915452ce66976f270d1cd793c3b0ab579cecd33c061053a8133610e5c565b60006105463447611a61565b9050610550610f04565b3461058f576040516356e4289360e01b81526020600482015260096024820152686d73672e76616c756560b81b60448201526064015b60405180910390fd5b84806105cf576040516356e4289360e01b815260206004820152600e60248201526d76616c696461746f72734461746160901b6044820152606401610586565b6105d881610f2c565b60007f000000000000000000000000d7c1b80fa86965b48cca3adccb08e1daea2919806001600160a01b03166369d421486040518163ffffffff1660e01b815260040160206040518083038186803b15801561063357600080fd5b505afa158015610647573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061066b9190611a78565b90506000816001600160a01b031663c44e30dc6040518163ffffffff1660e01b815260040160206040518083038186803b1580156106a857600080fd5b505afa1580156106bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e09190611a95565b905060006106ee8285611aae565b905060006106fb82610fc5565b905060008567ffffffffffffffff81111561071857610718611acd565b60405190808252806020026020018201604052801561074b57816020015b60608152602001906001900390816107365790505b50905060005b868110156107ef578c8c8281811061076b5761076b611ae3565b905060200281019061077d9190611af9565b61078b906040810190611b19565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050845185925084915081106107d3576107d3611ae3565b6020026020010181905250806107e890611b67565b9050610751565b50846001600160a01b031663eb3f512a84838967ffffffffffffffff81111561081a5761081a611acd565b604051908082528060200260200182016040528015610843578160200160208202803683370190505b506040518463ffffffff1660e01b8152600401610861929190611bda565b6000604051808303818588803b15801561087a57600080fd5b505af115801561088e573d6000803e3d6000fd5b505050505061089f8c8c868c610ff7565b6108a9828b6110f8565b5050505050508047146108be576108be611c7f565b505050505050565b6000908152600080516020611ee2833981519152602052604090206001015490565b6108f1826108c6565b6108fb8133610e5c565b6109058383611183565b505050565b6001600160a01b038116331461097a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610586565b61098482826111b2565b5050565b7f03c30da9b9e4d4789ac88a294d39a63058ca4a498804c2aa823e381df59d0cf46109b38133610e5c565b6109be8484846111e1565b50505050565b60006109dc600080516020611f028339815191525490565b905090565b6000828152600080516020611ec283398151915260205260408120610a069083611253565b9392505050565b6000918252600080516020611ee2833981519152602090815260408084206001600160a01b0393909316845291905290205460ff1690565b7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d610a708133610e5c565b6109848261125f565b6000610a91600080516020611f028339815191525490565b4210905090565b600080600080600080610ab8600080516020611f22833981519152610b77565b805160808201516060830151602084015163ffffffff9384169a50918316985082169650169350905085610aee57600019610af8565b610af881426112b3565b9150509091929394565b6000818152600080516020611ec2833981519152602052604081206104d390611377565b610b2f826108c6565b610b398133610e5c565b61090583836111b2565b7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d610b6e8133610e5c565b61098482611381565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152816040805160a081018252915463ffffffff8082168452640100000000820481166020850152600160401b8204811692840192909252600160601b810482166060840152600160801b900416608082015292915050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915263ffffffff851115610c4957604051635752823560e11b815260040160405180910390fd5b63ffffffff831115610c6e5760405163bbdd2da360e01b815260040160405180910390fd5b84841115610c8f5760405163528f486360e01b815260040160405180910390fd5b82610cad57604051636765a75d60e01b815260040160405180910390fd5b63ffffffff80851660808801528381166060880152602087015116851080610cda5750855163ffffffff16155b15610cec5763ffffffff851660208701525b5063ffffffff938416855290921660408401525090919050565b8051825460208301516040840151606085015160809095015163ffffffff94851667ffffffffffffffff199094169390931764010000000092851692909202919091176fffffffffffffffff00000000000000001916600160401b9184169190910263ffffffff60601b191617600160601b938316939093029290921763ffffffff60801b1916600160801b9190921602179055565b610da68282610a0d565b610984576000828152600080516020611ee2833981519152602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b6000610a06836001600160a01b0384166113d1565b60006001600160e01b03198216637965db0b60e01b14806104d357506301ffc9a760e01b6001600160e01b03198316146104d3565b610e668282610a0d565b61098457610e7e816001600160a01b03166014611420565b610e89836020611420565b604051602001610e9a929190611c95565b60408051601f198184030181529082905262461bcd60e51b825261058691600401611d0a565b610ec86115bc565b42600080516020611f02833981519152556040517f62451d457bc659158be6e6247f56ec1df424a5c7597f71c20c2bc44e0965c8f990600090a1565b610f0c610a79565b15610f2a57604051630286f07360e31b815260040160405180910390fd5b565b6000610f45600080516020611f22833981519152610b77565b9050610f57815163ffffffff16151590565b610f5f575050565b6000610f6b82426112b3565b905082811015610f985760405163106865a560e31b81526004810184905260248101829052604401610586565b610905610fb0610fa88584611a61565b8490426115e1565b600080516020611f2283398151915290610d06565b600081341015610ff15760405163a458261b60e01b815260048101839052346024820152604401610586565b50340390565b60007f000000000000000000000000d7c1b80fa86965b48cca3adccb08e1daea2919806001600160a01b031663ef6c064c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561105257600080fd5b505afa158015611066573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108a9190611a78565b604051637141658360e01b81529091506001600160a01b038216906371416583906110bf908890889088908890600401611d1d565b600060405180830381600087803b1580156110d957600080fd5b505af11580156110ed573d6000803e3d6000fd5b505050505050505050565b8115610984576001600160a01b03811661110f5750335b6000816001600160a01b03168360405160006040518083038185875af1925050503d806000811461115c576040519150601f19603f3d011682016040523d82523d6000602084013e611161565b606091505b505090508061090557604051637f832e9560e01b815260040160405180910390fd5b61118d8282610d9c565b6000828152600080516020611ec2833981519152602052604090206109059082610e12565b6111bc82826116b0565b6000828152600080516020611ec2833981519152602052604090206109059082611724565b4261120c610fb085858585611203600080516020611f22833981519152610b77565b93929190610bf9565b60408051858152602081018590529081018390527f3119d910326e0f179e121df55f23f45b8a5022ff10c73c02aabf2b48ae36070a9060600160405180910390a150505050565b6000610a068383611739565b611267610f04565b42811015611288576040516339e2ec5360e11b815260040160405180910390fd5b600060001982146112a55761129e826001611e06565b90506112aa565b506000195b61098481611763565b600080836040015163ffffffff16836112cc9190611a61565b9050836060015163ffffffff168110806112ee5750608084015163ffffffff16155b15611305575050602082015163ffffffff166104d3565b6000846060015163ffffffff168261131d9190611e1e565b90506000856080015163ffffffff16826113379190611aae565b9050600081876020015163ffffffff166113519190611e06565b875190915063ffffffff1681111561136d5750855163ffffffff165b9695505050505050565b60006104d3825490565b611389610f04565b806113a75760405163ad58bfc760e01b815260040160405180910390fd5b60006000198214156113bc57506000196112aa565b6113c68242611e06565b905061098481611763565b6000818152600183016020526040812054611418575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104d3565b5060006104d3565b6060600061142f836002611aae565b61143a906002611e06565b67ffffffffffffffff81111561145257611452611acd565b6040519080825280601f01601f19166020018201604052801561147c576020820181803683370190505b509050600360fc1b8160008151811061149757611497611ae3565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106114c6576114c6611ae3565b60200101906001600160f81b031916908160001a90535060006114ea846002611aae565b6114f5906001611e06565b90505b600181111561156d576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061152957611529611ae3565b1a60f81b82828151811061153f5761153f611ae3565b60200101906001600160f81b031916908160001a90535060049490941c9361156681611e40565b90506114f8565b508315610a065760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610586565b6115c4610a79565b610f2a5760405163b047186b60e01b815260040160405180910390fd5b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152835163ffffffff1683111561163457604051631930e3c960e11b815260040160405180910390fd5b6000846040015163ffffffff168361164c9190611a61565b90506000856060015163ffffffff16826116669190611e1e565b9050600086606001518261167a9190611e57565b63ffffffff87166020890152604088018051919250829161169c908390611e83565b63ffffffff16905250959695505050505050565b6116ba8282610a0d565b15610984576000828152600080516020611ee2833981519152602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000610a06836001600160a01b0384166117f6565b600082600001828154811061175057611750611ae3565b9060005260206000200154905092915050565b61177a600080516020611f02833981519152829055565b6000198114156117bd5760405160001981527f32fb7c9891bc4f963c7de9f1186d2a7755c7d6e9f4604dabe1d8bb3027c2f49e906020015b60405180910390a150565b7f32fb7c9891bc4f963c7de9f1186d2a7755c7d6e9f4604dabe1d8bb3027c2f49e6117e84283611a61565b6040519081526020016117b2565b600081815260018301602052604081205480156118df57600061181a600183611a61565b855490915060009061182e90600190611a61565b905081811461189357600086600001828154811061184e5761184e611ae3565b906000526020600020015490508087600001848154811061187157611871611ae3565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806118a4576118a4611eab565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104d3565b60009150506104d3565b6000602082840312156118fb57600080fd5b81356001600160e01b031981168114610a0657600080fd5b6001600160a01b038116811461050c57600080fd5b6000806000806060858703121561193e57600080fd5b843567ffffffffffffffff8082111561195657600080fd5b818701915087601f83011261196a57600080fd5b81358181111561197957600080fd5b8860208260051b850101111561198e57600080fd5b602092830196509450508501356119a481611913565b9396929550929360400135925050565b6000602082840312156119c657600080fd5b5035919050565b600080604083850312156119e057600080fd5b8235915060208301356119f281611913565b809150509250929050565b600080600060608486031215611a1257600080fd5b505081359360208301359350604090920135919050565b60008060408385031215611a3c57600080fd5b50508035926020909101359150565b634e487b7160e01b600052601160045260246000fd5b600082821015611a7357611a73611a4b565b500390565b600060208284031215611a8a57600080fd5b8151610a0681611913565b600060208284031215611aa757600080fd5b5051919050565b6000816000190483118215151615611ac857611ac8611a4b565b500290565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112611b0f57600080fd5b9190910192915050565b6000808335601e19843603018112611b3057600080fd5b83018035915067ffffffffffffffff821115611b4b57600080fd5b602001915036819003821315611b6057600080fd5b9250929050565b6000600019821415611b7b57611b7b611a4b565b5060010190565b60005b83811015611b9d578181015183820152602001611b85565b838111156109be5750506000910152565b60008151808452611bc6816020860160208601611b82565b601f01601f19169290920160200192915050565b6000604082016040835280855180835260608501915060608160051b8601019250602080880160005b83811015611c3157605f19888703018552611c1f868351611bae565b95509382019390820190600101611c03565b50508584038187015286518085528782019482019350915060005b82811015611c7257845167ffffffffffffffff1684529381019392810192600101611c4c565b5091979650505050505050565b634e487b7160e01b600052600160045260246000fd5b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611ccd816017850160208801611b82565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611cfe816028840160208801611b82565b01602801949350505050565b602081526000610a066020830184611bae565b60608082528181018590526000906080808401600588901b8501820189855b8a811015611dee57878303607f190184528135368d9003605e19018112611d6257600080fd5b8c01803584526020808201358186015260408083013536849003601e19018112611d8b57600080fd5b8301803567ffffffffffffffff811115611da457600080fd5b803603851315611db357600080fd5b8a83890152808b890152808483018b8a013760008882018b015297830197601f01601f19169096018801955050929092019150600101611d3c565b50506020860197909752505050506040015292915050565b60008219821115611e1957611e19611a4b565b500190565b600082611e3b57634e487b7160e01b600052601260045260246000fd5b500490565b600081611e4f57611e4f611a4b565b506000190190565b600063ffffffff80831681851681830481118215151615611e7a57611e7a611a4b565b02949350505050565b600063ffffffff808316818516808303821115611ea257611ea2611a4b565b01949350505050565b634e487b7160e01b600052603160045260246000fdfe8f8c450dae5029cd48cd91dd9db65da48fb742893edfc7941250f6721d93cbbe9a627a5d4aa7c17f87ff26e3fe9a42c2b6c559e8b41a42282d0ecebb17c0e4d3e8b012900cb200ee5dfc3b895a32791b67d12891b09f117814f167a237783a023a69583d449251314fd68e4e68fe89ca455d27f2701d2fdee1b16c585fc4e2d6a2646970667358221220d5db186c862dafc8c8d035ee0a29a267f14655bc8209a2edf0400781fd8e53f664736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000026edb7f0f223a25ee390accccb577f3a31eddfc5000000000000000000000000d7c1b80fa86965b48cca3adccb08e1daea29198000000000000000000000000000000000000000000000000000000000000032c800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000030
-----Decoded View---------------
Arg [0] : admin (address): 0x26EDb7f0f223A25EE390aCCccb577F3a31edDfC5
Arg [1] : lidoLocator (address): 0xD7c1B80fA86965B48cCA3aDcCB08E1DAEa291980
Arg [2] : maxExitRequestsLimit (uint256): 13000
Arg [3] : exitsPerFrame (uint256): 1
Arg [4] : frameDurationInSec (uint256): 48
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000026edb7f0f223a25ee390accccb577f3a31eddfc5
Arg [1] : 000000000000000000000000d7c1b80fa86965b48cca3adccb08e1daea291980
Arg [2] : 00000000000000000000000000000000000000000000000000000000000032c8
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000030
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
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.