CSParametersRegistry

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "src/CSParametersRegistry.sol": {
      "content": "// SPDX-FileCopyrightText: 2025 Lido <info@lido.fi>
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.24;

import { AccessControlEnumerableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol";
import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";

import { ICSParametersRegistry } from "./interfaces/ICSParametersRegistry.sol";

/// @dev There are no upper limit checks except for the basis points (BP) values
///      since with the introduction of Dual Governance any malicious changes to the parameters can be objected by stETH holders.
// solhint-disable-next-line max-states-count
contract CSParametersRegistry is
    ICSParametersRegistry,
    Initializable,
    AccessControlEnumerableUpgradeable
{
    using SafeCast for uint256;

    /// @dev Maximal value for basis points (BP)
    ///      1 BP = 0.01%
    uint256 internal constant MAX_BP = 10000;

    /// @dev QUEUE_LOWEST_PRIORITY identifies the range of available priorities: [0; QUEUE_LOWEST_PRIORITY].
    uint256 public immutable QUEUE_LOWEST_PRIORITY;
    /// @dev QUEUE_LEGACY_PRIORITY is the priority for the CSM v1 queue.
    uint256 public immutable QUEUE_LEGACY_PRIORITY;

    ////////////////////////
    // State variables below
    ////////////////////////

    uint256 public defaultKeyRemovalCharge;
    mapping(uint256 curveId => MarkedUint248) internal _keyRemovalCharges;

    uint256 public defaultElRewardsStealingAdditionalFine;
    mapping(uint256 curveId => MarkedUint248)
        internal _elRewardsStealingAdditionalFines;

    uint256 public defaultKeysLimit;
    mapping(uint256 curveId => MarkedUint248) internal _keysLimits;

    QueueConfig public defaultQueueConfig;
    mapping(uint256 curveId => QueueConfig) internal _queueConfigs;

    /// @dev Default value for the reward share. Can be only be set as a flat value due to possible sybil attacks
    ///      Decreased reward share for some validators > N will promote sybils. Increased reward share for validators > N will give large operators an advantage
    uint256 public defaultRewardShare;
    mapping(uint256 curveId => KeyNumberValueInterval[])
        internal _rewardShareData;

    /// @dev Default value for the performance leeway. Can be only be set as a flat value due to possible sybil attacks
    ///      Decreased performance leeway for some validators > N will promote sybils. Increased performance leeway for validators > N will give large operators an advantage
    uint256 public defaultPerformanceLeeway;
    mapping(uint256 curveId => KeyNumberValueInterval[])
        internal _performanceLeewayData;

    StrikesParams public defaultStrikesParams;
    mapping(uint256 curveId => StrikesParams) internal _strikesParams;

    uint256 public defaultBadPerformancePenalty;
    mapping(uint256 curveId => MarkedUint248) internal _badPerformancePenalties;

    PerformanceCoefficients public defaultPerformanceCoefficients;
    mapping(uint256 curveId => PerformanceCoefficients)
        internal _performanceCoefficients;

    uint256 public defaultAllowedExitDelay;
    mapping(uint256 => uint256) internal _allowedExitDelay;

    uint256 public defaultExitDelayPenalty;
    mapping(uint256 => MarkedUint248) internal _exitDelayPenalties;

    uint256 public defaultMaxWithdrawalRequestFee;
    mapping(uint256 => MarkedUint248) internal _maxWithdrawalRequestFees;

    constructor(uint256 queueLowestPriority) {
        if (queueLowestPriority == 0) {
            revert ZeroQueueLowestPriority();
        }

        QUEUE_LOWEST_PRIORITY = queueLowestPriority;
        QUEUE_LEGACY_PRIORITY = queueLowestPriority - 1;

        _disableInitializers();
    }

    /// @notice initialize contract
    function initialize(
        address admin,
        InitializationData calldata data
    ) external initializer {
        if (admin == address(0)) {
            revert ZeroAdminAddress();
        }

        _setDefaultKeyRemovalCharge(data.keyRemovalCharge);
        _setDefaultElRewardsStealingAdditionalFine(
            data.elRewardsStealingAdditionalFine
        );
        _setDefaultKeysLimit(data.keysLimit);
        _setDefaultRewardShare(data.rewardShare);
        _setDefaultPerformanceLeeway(data.performanceLeeway);
        _setDefaultStrikesParams(data.strikesLifetime, data.strikesThreshold);
        _setDefaultBadPerformancePenalty(data.badPerformancePenalty);
        _setDefaultPerformanceCoefficients(
            data.attestationsWeight,
            data.blocksWeight,
            data.syncWeight
        );
        _setDefaultQueueConfig(
            data.defaultQueuePriority,
            data.defaultQueueMaxDeposits
        );
        _setDefaultAllowedExitDelay(data.defaultAllowedExitDelay);
        _setDefaultExitDelayPenalty(data.defaultExitDelayPenalty);
        _setDefaultMaxWithdrawalRequestFee(data.defaultMaxWithdrawalRequestFee);

        __AccessControlEnumerable_init();

        _grantRole(DEFAULT_ADMIN_ROLE, admin);
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultKeyRemovalCharge(
        uint256 keyRemovalCharge
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultKeyRemovalCharge(keyRemovalCharge);
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultElRewardsStealingAdditionalFine(
        uint256 fine
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultElRewardsStealingAdditionalFine(fine);
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultKeysLimit(
        uint256 limit
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultKeysLimit(limit);
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultRewardShare(
        uint256 share
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultRewardShare(share);
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultPerformanceLeeway(
        uint256 leeway
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultPerformanceLeeway(leeway);
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultStrikesParams(
        uint256 lifetime,
        uint256 threshold
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultStrikesParams(lifetime, threshold);
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultBadPerformancePenalty(
        uint256 penalty
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultBadPerformancePenalty(penalty);
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultPerformanceCoefficients(
        uint256 attestationsWeight,
        uint256 blocksWeight,
        uint256 syncWeight
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultPerformanceCoefficients(
            attestationsWeight,
            blocksWeight,
            syncWeight
        );
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultQueueConfig(
        uint256 priority,
        uint256 maxDeposits
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultQueueConfig(priority, maxDeposits);
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultAllowedExitDelay(
        uint256 delay
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultAllowedExitDelay(delay);
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultExitDelayPenalty(
        uint256 penalty
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultExitDelayPenalty(penalty);
    }

    /// @inheritdoc ICSParametersRegistry
    function setDefaultMaxWithdrawalRequestFee(
        uint256 fee
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _setDefaultMaxWithdrawalRequestFee(fee);
    }

    /// @inheritdoc ICSParametersRegistry
    function setKeyRemovalCharge(
        uint256 curveId,
        uint256 keyRemovalCharge
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _keyRemovalCharges[curveId] = MarkedUint248(
            keyRemovalCharge.toUint248(),
            true
        );
        emit KeyRemovalChargeSet(curveId, keyRemovalCharge);
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetKeyRemovalCharge(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _keyRemovalCharges[curveId];
        emit KeyRemovalChargeUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function setElRewardsStealingAdditionalFine(
        uint256 curveId,
        uint256 fine
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _elRewardsStealingAdditionalFines[curveId] = MarkedUint248(
            fine.toUint248(),
            true
        );
        emit ElRewardsStealingAdditionalFineSet(curveId, fine);
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetElRewardsStealingAdditionalFine(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _elRewardsStealingAdditionalFines[curveId];
        emit ElRewardsStealingAdditionalFineUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function setKeysLimit(
        uint256 curveId,
        uint256 limit
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _keysLimits[curveId] = MarkedUint248(limit.toUint248(), true);
        emit KeysLimitSet(curveId, limit);
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetKeysLimit(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _keysLimits[curveId];
        emit KeysLimitUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function setRewardShareData(
        uint256 curveId,
        KeyNumberValueInterval[] calldata data
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _validateKeyNumberValueIntervals(data);
        KeyNumberValueInterval[] storage intervals = _rewardShareData[curveId];
        if (intervals.length > 0) {
            delete _rewardShareData[curveId];
        }
        for (uint256 i = 0; i < data.length; ++i) {
            intervals.push(data[i]);
        }
        emit RewardShareDataSet(curveId, data);
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetRewardShareData(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _rewardShareData[curveId];
        emit RewardShareDataUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function setPerformanceLeewayData(
        uint256 curveId,
        KeyNumberValueInterval[] calldata data
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _validateKeyNumberValueIntervals(data);
        KeyNumberValueInterval[] storage intervals = _performanceLeewayData[
            curveId
        ];
        if (intervals.length > 0) {
            delete _performanceLeewayData[curveId];
        }
        for (uint256 i = 0; i < data.length; ++i) {
            intervals.push(data[i]);
        }
        emit PerformanceLeewayDataSet(curveId, data);
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetPerformanceLeewayData(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _performanceLeewayData[curveId];
        emit PerformanceLeewayDataUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function setStrikesParams(
        uint256 curveId,
        uint256 lifetime,
        uint256 threshold
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _validateStrikesParams(lifetime, threshold);
        _strikesParams[curveId] = StrikesParams(
            lifetime.toUint32(),
            threshold.toUint32()
        );
        emit StrikesParamsSet(curveId, lifetime, threshold);
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetStrikesParams(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _strikesParams[curveId];
        emit StrikesParamsUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function setBadPerformancePenalty(
        uint256 curveId,
        uint256 penalty
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _badPerformancePenalties[curveId] = MarkedUint248(
            penalty.toUint248(),
            true
        );
        emit BadPerformancePenaltySet(curveId, penalty);
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetBadPerformancePenalty(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _badPerformancePenalties[curveId];
        emit BadPerformancePenaltyUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function setPerformanceCoefficients(
        uint256 curveId,
        uint256 attestationsWeight,
        uint256 blocksWeight,
        uint256 syncWeight
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _validatePerformanceCoefficients(
            attestationsWeight,
            blocksWeight,
            syncWeight
        );
        _performanceCoefficients[curveId] = PerformanceCoefficients(
            attestationsWeight.toUint32(),
            blocksWeight.toUint32(),
            syncWeight.toUint32()
        );
        emit PerformanceCoefficientsSet(
            curveId,
            attestationsWeight,
            blocksWeight,
            syncWeight
        );
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetPerformanceCoefficients(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _performanceCoefficients[curveId];
        emit PerformanceCoefficientsUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function setQueueConfig(
        uint256 curveId,
        uint256 priority,
        uint256 maxDeposits
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _validateQueueConfig(priority, maxDeposits);
        _queueConfigs[curveId] = QueueConfig({
            priority: priority.toUint32(),
            maxDeposits: maxDeposits.toUint32()
        });
        emit QueueConfigSet(curveId, priority, maxDeposits);
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetQueueConfig(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _queueConfigs[curveId];
        emit QueueConfigUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function setAllowedExitDelay(
        uint256 curveId,
        uint256 delay
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _validateAllowedExitDelay(delay);
        _allowedExitDelay[curveId] = delay;
        emit AllowedExitDelaySet(curveId, delay);
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetAllowedExitDelay(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _allowedExitDelay[curveId];
        emit AllowedExitDelayUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function setExitDelayPenalty(
        uint256 curveId,
        uint256 penalty
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _exitDelayPenalties[curveId] = MarkedUint248(penalty.toUint248(), true);
        emit ExitDelayPenaltySet(curveId, penalty);
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetExitDelayPenalty(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _exitDelayPenalties[curveId];
        emit ExitDelayPenaltyUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function setMaxWithdrawalRequestFee(
        uint256 curveId,
        uint256 fee
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        _maxWithdrawalRequestFees[curveId] = MarkedUint248(
            fee.toUint248(),
            true
        );
        emit MaxWithdrawalRequestFeeSet(curveId, fee);
    }

    /// @inheritdoc ICSParametersRegistry
    function unsetMaxWithdrawalRequestFee(
        uint256 curveId
    ) external onlyRole(DEFAULT_ADMIN_ROLE) {
        delete _maxWithdrawalRequestFees[curveId];
        emit MaxWithdrawalRequestFeeUnset(curveId);
    }

    /// @inheritdoc ICSParametersRegistry
    function getKeyRemovalCharge(
        uint256 curveId
    ) external view returns (uint256 keyRemovalCharge) {
        MarkedUint248 storage data = _keyRemovalCharges[curveId];
        return data.isValue ? data.value : defaultKeyRemovalCharge;
    }

    /// @inheritdoc ICSParametersRegistry
    function getElRewardsStealingAdditionalFine(
        uint256 curveId
    ) external view returns (uint256 fine) {
        MarkedUint248 storage data = _elRewardsStealingAdditionalFines[curveId];
        return
            data.isValue ? data.value : defaultElRewardsStealingAdditionalFine;
    }

    /// @inheritdoc ICSParametersRegistry
    function getKeysLimit(
        uint256 curveId
    ) external view returns (uint256 limit) {
        MarkedUint248 storage data = _keysLimits[curveId];
        return data.isValue ? data.value : defaultKeysLimit;
    }

    /// @inheritdoc ICSParametersRegistry
    function getRewardShareData(
        uint256 curveId
    ) external view returns (KeyNumberValueInterval[] memory data) {
        data = _rewardShareData[curveId];
        if (data.length == 0) {
            data = new KeyNumberValueInterval[](1);
            data[0] = KeyNumberValueInterval(1, defaultRewardShare);
        }
    }

    /// @inheritdoc ICSParametersRegistry
    function getPerformanceLeewayData(
        uint256 curveId
    ) external view returns (KeyNumberValueInterval[] memory data) {
        data = _performanceLeewayData[curveId];
        if (data.length == 0) {
            data = new KeyNumberValueInterval[](1);
            data[0] = KeyNumberValueInterval(1, defaultPerformanceLeeway);
        }
    }

    /// @inheritdoc ICSParametersRegistry
    function getStrikesParams(
        uint256 curveId
    ) external view returns (uint256 lifetime, uint256 threshold) {
        StrikesParams storage params = _strikesParams[curveId];
        if (params.threshold == 0) {
            return (
                defaultStrikesParams.lifetime,
                defaultStrikesParams.threshold
            );
        }
        return (params.lifetime, params.threshold);
    }

    /// @inheritdoc ICSParametersRegistry
    function getBadPerformancePenalty(
        uint256 curveId
    ) external view returns (uint256 penalty) {
        MarkedUint248 storage data = _badPerformancePenalties[curveId];
        return data.isValue ? data.value : defaultBadPerformancePenalty;
    }

    /// @inheritdoc ICSParametersRegistry
    function getPerformanceCoefficients(
        uint256 curveId
    )
        external
        view
        returns (
            uint256 attestationsWeight,
            uint256 blocksWeight,
            uint256 syncWeight
        )
    {
        PerformanceCoefficients storage coefficients = _performanceCoefficients[
            curveId
        ];
        if (
            coefficients.attestationsWeight == 0 &&
            coefficients.blocksWeight == 0 &&
            coefficients.syncWeight == 0
        ) {
            return (
                defaultPerformanceCoefficients.attestationsWeight,
                defaultPerformanceCoefficients.blocksWeight,
                defaultPerformanceCoefficients.syncWeight
            );
        }
        return (
            coefficients.attestationsWeight,
            coefficients.blocksWeight,
            coefficients.syncWeight
        );
    }

    /// @inheritdoc ICSParametersRegistry
    function getQueueConfig(
        uint256 curveId
    ) external view returns (uint32 queuePriority, uint32 maxDeposits) {
        QueueConfig storage config = _queueConfigs[curveId];

        if (config.maxDeposits == 0) {
            return (
                defaultQueueConfig.priority,
                defaultQueueConfig.maxDeposits
            );
        }

        return (config.priority, config.maxDeposits);
    }

    /// @inheritdoc ICSParametersRegistry
    function getAllowedExitDelay(
        uint256 curveId
    ) external view returns (uint256 delay) {
        delay = _allowedExitDelay[curveId];
        if (delay == 0) {
            return defaultAllowedExitDelay;
        }
    }

    /// @inheritdoc ICSParametersRegistry
    function getExitDelayPenalty(
        uint256 curveId
    ) external view returns (uint256 penalty) {
        MarkedUint248 memory data = _exitDelayPenalties[curveId];
        return data.isValue ? data.value : defaultExitDelayPenalty;
    }

    /// @inheritdoc ICSParametersRegistry
    function getMaxWithdrawalRequestFee(
        uint256 curveId
    ) external view returns (uint256 fee) {
        MarkedUint248 memory data = _maxWithdrawalRequestFees[curveId];
        return data.isValue ? data.value : defaultMaxWithdrawalRequestFee;
    }

    /// @inheritdoc ICSParametersRegistry
    function getInitializedVersion() external view returns (uint64) {
        return _getInitializedVersion();
    }

    function _setDefaultKeyRemovalCharge(uint256 keyRemovalCharge) internal {
        defaultKeyRemovalCharge = keyRemovalCharge;
        emit DefaultKeyRemovalChargeSet(keyRemovalCharge);
    }

    function _setDefaultElRewardsStealingAdditionalFine(uint256 fine) internal {
        defaultElRewardsStealingAdditionalFine = fine;
        emit DefaultElRewardsStealingAdditionalFineSet(fine);
    }

    function _setDefaultKeysLimit(uint256 limit) internal {
        defaultKeysLimit = limit;
        emit DefaultKeysLimitSet(limit);
    }

    function _setDefaultRewardShare(uint256 share) internal {
        if (share > MAX_BP) {
            revert InvalidRewardShareData();
        }

        defaultRewardShare = share;
        emit DefaultRewardShareSet(share);
    }

    function _setDefaultPerformanceLeeway(uint256 leeway) internal {
        if (leeway > MAX_BP) {
            revert InvalidPerformanceLeewayData();
        }

        defaultPerformanceLeeway = leeway;
        emit DefaultPerformanceLeewaySet(leeway);
    }

    function _setDefaultStrikesParams(
        uint256 lifetime,
        uint256 threshold
    ) internal {
        _validateStrikesParams(lifetime, threshold);
        defaultStrikesParams = StrikesParams({
            lifetime: lifetime.toUint32(),
            threshold: threshold.toUint32()
        });
        emit DefaultStrikesParamsSet(lifetime, threshold);
    }

    function _setDefaultBadPerformancePenalty(uint256 penalty) internal {
        defaultBadPerformancePenalty = penalty;
        emit DefaultBadPerformancePenaltySet(penalty);
    }

    function _setDefaultPerformanceCoefficients(
        uint256 attestationsWeight,
        uint256 blocksWeight,
        uint256 syncWeight
    ) internal {
        _validatePerformanceCoefficients(
            attestationsWeight,
            blocksWeight,
            syncWeight
        );
        defaultPerformanceCoefficients = PerformanceCoefficients({
            attestationsWeight: attestationsWeight.toUint32(),
            blocksWeight: blocksWeight.toUint32(),
            syncWeight: syncWeight.toUint32()
        });
        emit DefaultPerformanceCoefficientsSet(
            attestationsWeight,
            blocksWeight,
            syncWeight
        );
    }

    function _setDefaultQueueConfig(
        uint256 priority,
        uint256 maxDeposits
    ) internal {
        _validateQueueConfig(priority, maxDeposits);
        defaultQueueConfig = QueueConfig({
            priority: priority.toUint32(),
            maxDeposits: maxDeposits.toUint32()
        });
        emit DefaultQueueConfigSet(priority, maxDeposits);
    }

    function _setDefaultAllowedExitDelay(uint256 delay) internal {
        _validateAllowedExitDelay(delay);
        defaultAllowedExitDelay = delay;
        emit DefaultAllowedExitDelaySet(delay);
    }

    function _setDefaultExitDelayPenalty(uint256 penalty) internal {
        defaultExitDelayPenalty = penalty;
        emit DefaultExitDelayPenaltySet(penalty);
    }

    function _setDefaultMaxWithdrawalRequestFee(uint256 fee) internal {
        defaultMaxWithdrawalRequestFee = fee;
        emit DefaultMaxWithdrawalRequestFeeSet(fee);
    }

    function _validateQueueConfig(
        uint256 priority,
        uint256 maxDeposits
    ) internal view {
        if (
            priority > QUEUE_LOWEST_PRIORITY ||
            priority == QUEUE_LEGACY_PRIORITY
        ) {
            revert QueueCannotBeUsed();
        }
        if (maxDeposits == 0) {
            revert ZeroMaxDeposits();
        }
    }

    function _validateStrikesParams(
        uint256 lifetime,
        uint256 threshold
    ) internal pure {
        if (threshold == 0 || lifetime == 0) {
            revert InvalidStrikesParams();
        }
    }

    function _validateAllowedExitDelay(uint256 delay) internal pure {
        if (delay == 0) {
            revert InvalidAllowedExitDelay();
        }
    }

    function _validatePerformanceCoefficients(
        uint256 attestationsWeight,
        uint256 blocksWeight,
        uint256 syncWeight
    ) internal pure {
        if (attestationsWeight == 0 && blocksWeight == 0 && syncWeight == 0) {
            revert InvalidPerformanceCoefficients();
        }
    }

    function _validateKeyNumberValueIntervals(
        KeyNumberValueInterval[] calldata intervals
    ) private pure {
        if (intervals.length == 0) {
            revert InvalidKeyNumberValueIntervals();
        }
        if (intervals[0].minKeyNumber != 1) {
            revert InvalidKeyNumberValueIntervals();
        }

        if (intervals[0].value > MAX_BP) {
            revert InvalidKeyNumberValueIntervals();
        }

        for (uint256 i = 1; i < intervals.length; ++i) {
            unchecked {
                if (
                    intervals[i].minKeyNumber <= intervals[i - 1].minKeyNumber
                ) {
                    revert InvalidKeyNumberValueIntervals();
                }
                if (intervals[i].value > MAX_BP) {
                    revert InvalidKeyNumberValueIntervals();
                }
            }
        }
    }
}
"
    },
    "node_modules/@openzeppelin/contracts-upgradeable/access/extensions/AccessControlEnumerableUpgradeable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/extensions/AccessControlEnumerable.sol)

pragma solidity ^0.8.20;

import {IAccessControlEnumerable} from "@openzeppelin/contracts/access/extensions/IAccessControlEnumerable.sol";
import {AccessControlUpgradeable} from "../AccessControlUpgradeable.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";

/**
 * @dev Extension of {AccessControl} that allows enumerating the members of each role.
 */
abstract contract AccessControlEnumerableUpgradeable is Initializable, IAccessControlEnumerable, AccessControlUpgradeable {
    using EnumerableSet for EnumerableSet.AddressSet;

    /// @custom:storage-location erc7201:openzeppelin.storage.AccessControlEnumerable
    struct AccessControlEnumerableStorage {
        mapping(bytes32 role => EnumerableSet.AddressSet) _roleMembers;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.AccessControlEnumerable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant AccessControlEnumerableStorageLocation = 0xc1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e82371705932000;

    function _getAccessControlEnumerableStorage() private pure returns (AccessControlEnumerableStorage storage $) {
        assembly {
            $.slot := AccessControlEnumerableStorageLocation
        }
    }

    function __AccessControlEnumerable_init() internal onlyInitializing {
    }

    function __AccessControlEnumerable_init_unchained() internal onlyInitializing {
    }
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view virtual returns (address) {
        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();
        return $._roleMembers[role].at(index);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view virtual returns (uint256) {
        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();
        return $._roleMembers[role].length();
    }

    /**
     * @dev Overload {AccessControl-_grantRole} to track enumerable memberships
     */
    function _grantRole(bytes32 role, address account) internal virtual override returns (bool) {
        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();
        bool granted = super._grantRole(role, account);
        if (granted) {
            $._roleMembers[role].add(account);
        }
        return granted;
    }

    /**
     * @dev Overload {AccessControl-_revokeRole} to track enumerable memberships
     */
    function _revokeRole(bytes32 role, address account) internal virtual override returns (bool) {
        AccessControlEnumerableStorage storage $ = _getAccessControlEnumerableStorage();
        bool revoked = super._revokeRole(role, account);
        if (revoked) {
            $._roleMembers[role].remove(account);
        }
        return revoked;
    }
}
"
    },
    "node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.20;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Storage of the initializable contract.
     *
     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
     * when using with upgradeable contracts.
     *
     * @custom:storage-location erc7201:openzeppelin.storage.Initializable
     */
    struct InitializableStorage {
        /**
         * @dev Indicates that the contract has been initialized.
         */
        uint64 _initialized;
        /**
         * @dev Indicates that the contract is in the process of being initialized.
         */
        bool _initializing;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;

    /**
     * @dev The contract is already initialized.
     */
    error InvalidInitialization();

    /**
     * @dev The contract is not initializing.
     */
    error NotInitializing();

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint64 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
     * production.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        // Cache values to avoid duplicated sloads
        bool isTopLevelCall = !$._initializing;
        uint64 initialized = $._initialized;

        // Allowed calls:
        // - initialSetup: the contract is not in the initializing state and no previous version was
        //                 initialized
        // - construction: the contract is initialized at version 1 (no reininitialization) and the
        //                 current contract is just being deployed
        bool initialSetup = initialized == 0 && isTopLevelCall;
        bool construction = initialized == 1 && address(this).code.length == 0;

        if (!initialSetup && !construction) {
            revert InvalidInitialization();
        }
        $._initialized = 1;
        if (isTopLevelCall) {
            $._initializing = true;
        }
        _;
        if (isTopLevelCall) {
            $._initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint64 version) {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing || $._initialized >= version) {
            revert InvalidInitialization();
        }
        $._initialized = version;
        $._initializing = true;
        _;
        $._initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        _checkInitializing();
        _;
    }

    /**
     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
     */
    function _checkInitializing() internal view virtual {
        if (!_isInitializing()) {
            revert NotInitializing();
        }
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing) {
            revert InvalidInitialization();
        }
        if ($._initialized != type(uint64).max) {
            $._initialized = type(uint64).max;
            emit Initialized(type(uint64).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint64) {
        return _getInitializableStorage()._initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _getInitializableStorage()._initializing;
    }

    /**
     * @dev Returns a pointer to the storage namespace.
     */
    // solhint-disable-next-line var-name-mixedcase
    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
        assembly {
            $.slot := INITIALIZABLE_STORAGE
        }
    }
}
"
    },
    "node_modules/@openzeppelin/contracts/utils/math/SafeCast.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.

pragma solidity ^0.8.20;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeCast {
    /**
     * @dev Value doesn't fit in an uint of `bits` size.
     */
    error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);

    /**
     * @dev An int value doesn't fit in an uint of `bits` size.
     */
    error SafeCastOverflowedIntToUint(int256 value);

    /**
     * @dev Value doesn't fit in an int of `bits` size.
     */
    error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);

    /**
     * @dev An uint value doesn't fit in an int of `bits` size.
     */
    error SafeCastOverflowedUintToInt(uint256 value);

    /**
     * @dev Returns the downcasted uint248 from uint256, reverting on
     * overflow (when the input is greater than largest uint248).
     *
     * Counterpart to Solidity's `uint248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     */
    function toUint248(uint256 value) internal pure returns (uint248) {
        if (value > type(uint248).max) {
            revert SafeCastOverflowedUintDowncast(248, value);
        }
        return uint248(value);
    }

    /**
     * @dev Returns the downcasted uint240 from uint256, reverting on
     * overflow (when the input is greater than largest uint240).
     *
     * Counterpart to Solidity's `uint240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     */
    function toUint240(uint256 value) internal pure returns (uint240) {
        if (value > type(uint240).max) {
            revert SafeCastOverflowedUintDowncast(240, value);
        }
        return uint240(value);
    }

    /**
     * @dev Returns the downcasted uint232 from uint256, reverting on
     * overflow (when the input is greater than largest uint232).
     *
     * Counterpart to Solidity's `uint232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     */
    function toUint232(uint256 value) internal pure returns (uint232) {
        if (value > type(uint232).max) {
            revert SafeCastOverflowedUintDowncast(232, value);
        }
        return uint232(value);
    }

    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        if (value > type(uint224).max) {
            revert SafeCastOverflowedUintDowncast(224, value);
        }
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint216 from uint256, reverting on
     * overflow (when the input is greater than largest uint216).
     *
     * Counterpart to Solidity's `uint216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     */
    function toUint216(uint256 value) internal pure returns (uint216) {
        if (value > type(uint216).max) {
            revert SafeCastOverflowedUintDowncast(216, value);
        }
        return uint216(value);
    }

    /**
     * @dev Returns the downcasted uint208 from uint256, reverting on
     * overflow (when the input is greater than largest uint208).
     *
     * Counterpart to Solidity's `uint208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     */
    function toUint208(uint256 value) internal pure returns (uint208) {
        if (value > type(uint208).max) {
            revert SafeCastOverflowedUintDowncast(208, value);
        }
        return uint208(value);
    }

    /**
     * @dev Returns the downcasted uint200 from uint256, reverting on
     * overflow (when the input is greater than largest uint200).
     *
     * Counterpart to Solidity's `uint200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     */
    function toUint200(uint256 value) internal pure returns (uint200) {
        if (value > type(uint200).max) {
            revert SafeCastOverflowedUintDowncast(200, value);
        }
        return uint200(value);
    }

    /**
     * @dev Returns the downcasted uint192 from uint256, reverting on
     * overflow (when the input is greater than largest uint192).
     *
     * Counterpart to Solidity's `uint192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     */
    function toUint192(uint256 value) internal pure returns (uint192) {
        if (value > type(uint192).max) {
            revert SafeCastOverflowedUintDowncast(192, value);
        }
        return uint192(value);
    }

    /**
     * @dev Returns the downcasted uint184 from uint256, reverting on
     * overflow (when the input is greater than largest uint184).
     *
     * Counterpart to Solidity's `uint184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     */
    function toUint184(uint256 value) internal pure returns (uint184) {
        if (value > type(uint184).max) {
            revert SafeCastOverflowedUintDowncast(184, value);
        }
        return uint184(value);
    }

    /**
     * @dev Returns the downcasted uint176 from uint256, reverting on
     * overflow (when the input is greater than largest uint176).
     *
     * Counterpart to Solidity's `uint176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     */
    function toUint176(uint256 value) internal pure returns (uint176) {
        if (value > type(uint176).max) {
            revert SafeCastOverflowedUintDowncast(176, value);
        }
        return uint176(value);
    }

    /**
     * @dev Returns the downcasted uint168 from uint256, reverting on
     * overflow (when the input is greater than largest uint168).
     *
     * Counterpart to Solidity's `uint168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     */
    function toUint168(uint256 value) internal pure returns (uint168) {
        if (value > type(uint168).max) {
            revert SafeCastOverflowedUintDowncast(168, value);
        }
        return uint168(value);
    }

    /**
     * @dev Returns the downcasted uint160 from uint256, reverting on
     * overflow (when the input is greater than largest uint160).
     *
     * Counterpart to Solidity's `uint160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     */
    function toUint160(uint256 value) internal pure returns (uint160) {
        if (value > type(uint160).max) {
            revert SafeCastOverflowedUintDowncast(160, value);
        }
        return uint160(value);
    }

    /**
     * @dev Returns the downcasted uint152 from uint256, reverting on
     * overflow (when the input is greater than largest uint152).
     *
     * Counterpart to Solidity's `uint152` operator.
     *
     * Requirements:
     *
     * - input must fit into 152 bits
     */
    function toUint152(uint256 value) internal pure returns (uint152) {
        if (value > type(uint152).max) {
            revert SafeCastOverflowedUintDowncast(152, value);
        }
        return uint152(value);
    }

    /**
     * @dev Returns the downcasted uint144 from uint256, reverting on
     * overflow (when the input is greater than largest uint144).
     *
     * Counterpart to Solidity's `uint144` operator.
     *
     * Requirements:
     *
     * - input must fit into 144 bits
     */
    function toUint144(uint256 value) internal pure returns (uint144) {
        if (value > type(uint144).max) {
            revert SafeCastOverflowedUintDowncast(144, value);
        }
        return uint144(value);
    }

    /**
     * @dev Returns the downcasted uint136 from uint256, reverting on
     * overflow (when the input is greater than largest uint136).
     *
     * Counterpart to Solidity's `uint136` operator.
     *
     * Requirements:
     *
     * - input must fit into 136 bits
     */
    function toUint136(uint256 value) internal pure returns (uint136) {
        if (value > type(uint136).max) {
            revert SafeCastOverflowedUintDowncast(136, value);
        }
        return uint136(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        if (value > type(uint128).max) {
            revert SafeCastOverflowedUintDowncast(128, value);
        }
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint120 from uint256, reverting on
     * overflow (when the input is greater than largest uint120).
     *
     * Counterpart to Solidity's `uint120` operator.
     *
     * Requirements:
     *
     * - input must fit into 120 bits
     */
    function toUint120(uint256 value) internal pure returns (uint120) {
        if (value > type(uint120).max) {
            revert SafeCastOverflowedUintDowncast(120, value);
        }
        return uint120(value);
    }

    /**
     * @dev Returns the downcasted uint112 from uint256, reverting on
     * overflow (when the input is greater than largest uint112).
     *
     * Counterpart to Solidity's `uint112` operator.
     *
     * Requirements:
     *
     * - input must fit into 112 bits
     */
    function toUint112(uint256 value) internal pure returns (uint112) {
        if (value > type(uint112).max) {
            revert SafeCastOverflowedUintDowncast(112, value);
        }
        return uint112(value);
    }

    /**
     * @dev Returns the downcasted uint104 from uint256, reverting on
     * overflow (when the input is greater than largest uint104).
     *
     * Counterpart to Solidity's `uint104` operator.
     *
     * Requirements:
     *
     * - input must fit into 104 bits
     */
    function toUint104(uint256 value) internal pure returns (uint104) {
        if (value > type(uint104).max) {
            revert SafeCastOverflowedUintDowncast(104, value);
        }
        return uint104(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        if (value > type(uint96).max) {
            revert SafeCastOverflowedUintDowncast(96, value);
        }
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint88 from uint256, reverting on
     * overflow (when the input is greater than largest uint88).
     *
     * Counterpart to Solidity's `uint88` operator.
     *
     * Requirements:
     *
     * - input must fit into 88 bits
     */
    function toUint88(uint256 value) internal pure returns (uint88) {
        if (value > type(uint88).max) {
            revert SafeCastOverflowedUintDowncast(88, value);
        }
        return uint88(value);
    }

    /**
     * @dev Returns the downcasted uint80 from uint256, reverting on
     * overflow (when the input is greater than largest uint80).
     *
     * Counterpart to Solidity's `uint80` operator.
     *
     * Requirements:
     *
     * - input must fit into 80 bits
     */
    function toUint80(uint256 value) internal pure returns (uint80) {
        if (value > type(uint80).max) {
            revert SafeCastOverflowedUintDowncast(80, value);
        }
        return uint80(value);
    }

    /**
     * @dev Returns the downcasted uint72 from uint256, reverting on
     * overflow (when the input is greater than largest uint72).
     *
     * Counterpart to Solidity's `uint72` operator.
     *
     * Requirements:
     *
     * - input must fit into 72 bits
     */
    function toUint72(uint256 value) internal pure returns (uint72) {
        if (value > type(uint72).max) {
            revert SafeCastOverflowedUintDowncast(72, value);
        }
        return uint72(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        if (value > type(uint64).max) {
            revert SafeCastOverflowedUintDowncast(64, value);
        }
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint56 from uint256, reverting on
     * overflow (when the input is greater than largest uint56).
     *
     * Counterpart to Solidity's `uint56` operator.
     *
     * Requirements:
     *
     * - input must fit into 56 bits
     */
    function toUint56(uint256 value) internal pure returns (uint56) {
        if (value > type(uint56).max) {
            revert SafeCastOverflowedUintDowncast(56, value);
        }
        return uint56(value);
    }

    /**
     * @dev Returns the downcasted uint48 from uint256, reverting on
     * overflow (when the input is greater than largest uint48).
     *
     * Counterpart to Solidity's `uint48` operator.
     *
     * Requirements:
     *
     * - input must fit into 48 bits
     */
    function toUint48(uint256 value) internal pure returns (uint48) {
        if (value > type(uint48).max) {
            revert SafeCastOverflowedUintDowncast(48, value);
        }
        return uint48(value);
    }

    /**
     * @dev Returns the downcasted uint40 from uint256, reverting on
     * overflow (when the input is greater than largest uint40).
     *
     * Counterpart to Solidity's `uint40` operator.
     *
     * Requirements:
     *
     * - input must fit into 40 bits
     */
    function toUint40(uint256 value) internal pure returns (uint40) {
        if (value > type(uint40).max) {
            revert SafeCastOverflowedUintDowncast(40, value);
        }
        return uint40(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        if (value > type(uint32).max) {
            revert SafeCastOverflowedUintDowncast(32, value);
        }
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint24 from uint256, reverting on
     * overflow (when the input is greater than largest uint24).
     *
     * Counterpart to Solidity's `uint24` operator.
     *
     * Requirements:
     *
     * - input must fit into 24 bits
     */
    function toUint24(uint256 value) internal pure returns (uint24) {
        if (value > type(uint24).max) {
            revert SafeCastOverflowedUintDowncast(24, value);
        }
        return uint24(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        if (value > type(uint16).max) {
            revert SafeCastOverflowedUintDowncast(16, value);
        }
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        if (value > type(uint8).max) {
            revert SafeCastOverflowedUintDowncast(8, value);
        }
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        if (value < 0) {
            revert SafeCastOverflowedIntToUint(value);
        }
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int248 from int256, reverting on
     * overflow (when the input is less than smallest int248 or
     * greater than largest int248).
     *
     * Counterpart to Solidity's `int248` operator.
     *
     * Requirements:
     *
     * - input must fit into 248 bits
     */
    function toInt248(int256 value) internal pure returns (int248 downcasted) {
        downcasted = int248(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(248, value);
        }
    }

    /**
     * @dev Returns the downcasted int240 from int256, reverting on
     * overflow (when the input is less than smallest int240 or
     * greater than largest int240).
     *
     * Counterpart to Solidity's `int240` operator.
     *
     * Requirements:
     *
     * - input must fit into 240 bits
     */
    function toInt240(int256 value) internal pure returns (int240 downcasted) {
        downcasted = int240(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(240, value);
        }
    }

    /**
     * @dev Returns the downcasted int232 from int256, reverting on
     * overflow (when the input is less than smallest int232 or
     * greater than largest int232).
     *
     * Counterpart to Solidity's `int232` operator.
     *
     * Requirements:
     *
     * - input must fit into 232 bits
     */
    function toInt232(int256 value) internal pure returns (int232 downcasted) {
        downcasted = int232(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(232, value);
        }
    }

    /**
     * @dev Returns the downcasted int224 from int256, reverting on
     * overflow (when the input is less than smallest int224 or
     * greater than largest int224).
     *
     * Counterpart to Solidity's `int224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toInt224(int256 value) internal pure returns (int224 downcasted) {
        downcasted = int224(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(224, value);
        }
    }

    /**
     * @dev Returns the downcasted int216 from int256, reverting on
     * overflow (when the input is less than smallest int216 or
     * greater than largest int216).
     *
     * Counterpart to Solidity's `int216` operator.
     *
     * Requirements:
     *
     * - input must fit into 216 bits
     */
    function toInt216(int256 value) internal pure returns (int216 downcasted) {
        downcasted = int216(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(216, value);
        }
    }

    /**
     * @dev Returns the downcasted int208 from int256, reverting on
     * overflow (when the input is less than smallest int208 or
     * greater than largest int208).
     *
     * Counterpart to Solidity's `int208` operator.
     *
     * Requirements:
     *
     * - input must fit into 208 bits
     */
    function toInt208(int256 value) internal pure returns (int208 downcasted) {
        downcasted = int208(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(208, value);
        }
    }

    /**
     * @dev Returns the downcasted int200 from int256, reverting on
     * overflow (when the input is less than smallest int200 or
     * greater than largest int200).
     *
     * Counterpart to Solidity's `int200` operator.
     *
     * Requirements:
     *
     * - input must fit into 200 bits
     */
    function toInt200(int256 value) internal pure returns (int200 downcasted) {
        downcasted = int200(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(200, value);
        }
    }

    /**
     * @dev Returns the downcasted int192 from int256, reverting on
     * overflow (when the input is less than smallest int192 or
     * greater than largest int192).
     *
     * Counterpart to Solidity's `int192` operator.
     *
     * Requirements:
     *
     * - input must fit into 192 bits
     */
    function toInt192(int256 value) internal pure returns (int192 downcasted) {
        downcasted = int192(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(192, value);
        }
    }

    /**
     * @dev Returns the downcasted int184 from int256, reverting on
     * overflow (when the input is less than smallest int184 or
     * greater than largest int184).
     *
     * Counterpart to Solidity's `int184` operator.
     *
     * Requirements:
     *
     * - input must fit into 184 bits
     */
    function toInt184(int256 value) internal pure returns (int184 downcasted) {
        downcasted = int184(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(184, value);
        }
    }

    /**
     * @dev Returns the downcasted int176 from int256, reverting on
     * overflow (when the input is less than smallest int176 or
     * greater than largest int176).
     *
     * Counterpart to Solidity's `int176` operator.
     *
     * Requirements:
     *
     * - input must fit into 176 bits
     */
    function toInt176(int256 value) internal pure returns (int176 downcasted) {
        downcasted = int176(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(176, value);
        }
    }

    /**
     * @dev Returns the downcasted int168 from int256, reverting on
     * overflow (when the input is less than smallest int168 or
     * greater than largest int168).
     *
     * Counterpart to Solidity's `int168` operator.
     *
     * Requirements:
     *
     * - input must fit into 168 bits
     */
    function toInt168(int256 value) internal pure returns (int168 downcasted) {
        downcasted = int168(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(168, value);
        }
    }

    /**
     * @dev Returns the downcasted int160 from int256, reverting on
     * overflow (when the input is less than smallest int160 or
     * greater than largest int160).
     *
     * Counterpart to Solidity's `int160` operator.
     *
     * Requirements:
     *
     * - input must fit into 160 bits
     */
    function toInt160(int256 value) internal pure returns (int160 downcasted) {
        downcasted = int160(value);
        if (downcasted != value) {
            revert SafeCastOverflowedIntDowncast(160, value);
        }
    }

    /**
     * @dev Returns the downcasted int152 from int256, reverting on
     * overflow (when the input is less than smallest int152 or
     * greater than largest int152).
     *
    

Tags:
ERC165, Multisig, Voting, Upgradeable, Multi-Signature, Factory, Oracle|addr:0x25fdc3be9977cd4da679df72a64c8b6bd5216a78|verified:true|block:23382820|tx:0x4104b33590ea10ba8a52e6ea6af0637b0ae0f366109674e67dafa99c313208f2|first_check:1758119800

Submitted on: 2025-09-17 16:36:41

Comments

Log in to comment.

No comments yet.