{"sources":{"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```solidity\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n *\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Storage of the initializable contract.\n     *\n     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\n     * when using with upgradeable contracts.\n     *\n     * @custom:storage-location erc7201:openzeppelin.storage.Initializable\n     */\n    struct InitializableStorage {\n        /**\n         * @dev Indicates that the contract has been initialized.\n         */\n        uint64 _initialized;\n        /**\n         * @dev Indicates that the contract is in the process of being initialized.\n         */\n        bool _initializing;\n    }\n\n    // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.Initializable\")) - 1)) & ~bytes32(uint256(0xff))\n    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\n\n    /**\n     * @dev The contract is already initialized.\n     */\n    error InvalidInitialization();\n\n    /**\n     * @dev The contract is not initializing.\n     */\n    error NotInitializing();\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint64 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts.\n     *\n     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\n     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\n     * production.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier initializer() {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        // Cache values to avoid duplicated sloads\n        bool isTopLevelCall = !$._initializing;\n        uint64 initialized = $._initialized;\n\n        // Allowed calls:\n        // - initialSetup: the contract is not in the initializing state and no previous version was\n        //                 initialized\n        // - construction: the contract is initialized at version 1 (no reininitialization) and the\n        //                 current contract is just being deployed\n        bool initialSetup = initialized == 0 && isTopLevelCall;\n        bool construction = initialized == 1 && address(this).code.length == 0;\n\n        if (!initialSetup && !construction) {\n            revert InvalidInitialization();\n        }\n        $._initialized = 1;\n        if (isTopLevelCall) {\n            $._initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            $._initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * A reinitializer may be used after the original initialization step. This is essential to configure modules that\n     * are added through upgrades and that require initialization.\n     *\n     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\n     * cannot be nested. If one is invoked in the context of another, execution will revert.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     *\n     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\n     *\n     * Emits an {Initialized} event.\n     */\n    modifier reinitializer(uint64 version) {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing || $._initialized >= version) {\n            revert InvalidInitialization();\n        }\n        $._initialized = version;\n        $._initializing = true;\n        _;\n        $._initializing = false;\n        emit Initialized(version);\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        _checkInitializing();\n        _;\n    }\n\n    /**\n     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\n     */\n    function _checkInitializing() internal view virtual {\n        if (!_isInitializing()) {\n            revert NotInitializing();\n        }\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     *\n     * Emits an {Initialized} event the first time it is successfully executed.\n     */\n    function _disableInitializers() internal virtual {\n        // solhint-disable-next-line var-name-mixedcase\n        InitializableStorage storage $ = _getInitializableStorage();\n\n        if ($._initializing) {\n            revert InvalidInitialization();\n        }\n        if ($._initialized != type(uint64).max) {\n            $._initialized = type(uint64).max;\n            emit Initialized(type(uint64).max);\n        }\n    }\n\n    /**\n     * @dev Returns the highest version that has been initialized. See {reinitializer}.\n     */\n    function _getInitializedVersion() internal view returns (uint64) {\n        return _getInitializableStorage()._initialized;\n    }\n\n    /**\n     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\n     */\n    function _isInitializing() internal view returns (bool) {\n        return _getInitializableStorage()._initializing;\n    }\n\n    /**\n     * @dev Returns a pointer to the storage namespace.\n     */\n    // solhint-disable-next-line var-name-mixedcase\n    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\n        assembly {\n            $.slot := INITIALIZABLE_STORAGE\n        }\n    }\n}\n"},"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (proxy/utils/UUPSUpgradeable.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC1822Proxiable} from \"@openzeppelin/contracts/interfaces/draft-IERC1822.sol\";\nimport {ERC1967Utils} from \"@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol\";\nimport {Initializable} from \"./Initializable.sol\";\n\n/**\n * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an\n * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.\n *\n * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is\n * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing\n * `UUPSUpgradeable` with a custom implementation of upgrades.\n *\n * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.\n */\nabstract contract UUPSUpgradeable is Initializable, IERC1822Proxiable {\n    /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n    address private immutable __self = address(this);\n\n    /**\n     * @dev The version of the upgrade interface of the contract. If this getter is missing, both `upgradeTo(address)`\n     * and `upgradeToAndCall(address,bytes)` are present, and `upgradeTo` must be used if no function should be called,\n     * while `upgradeToAndCall` will invoke the `receive` function if the second argument is the empty byte string.\n     * If the getter returns `\"5.0.0\"`, only `upgradeToAndCall(address,bytes)` is present, and the second argument must\n     * be the empty byte string if no function should be called, making it impossible to invoke the `receive` function\n     * during an upgrade.\n     */\n    string public constant UPGRADE_INTERFACE_VERSION = \"5.0.0\";\n\n    /**\n     * @dev The call is from an unauthorized context.\n     */\n    error UUPSUnauthorizedCallContext();\n\n    /**\n     * @dev The storage `slot` is unsupported as a UUID.\n     */\n    error UUPSUnsupportedProxiableUUID(bytes32 slot);\n\n    /**\n     * @dev Check that the execution is being performed through a delegatecall call and that the execution context is\n     * a proxy contract with an implementation (as defined in ERC-1967) pointing to self. This should only be the case\n     * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a\n     * function through ERC-1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to\n     * fail.\n     */\n    modifier onlyProxy() {\n        _checkProxy();\n        _;\n    }\n\n    /**\n     * @dev Check that the execution is not being performed through a delegate call. This allows a function to be\n     * callable on the implementing contract but not through proxies.\n     */\n    modifier notDelegated() {\n        _checkNotDelegated();\n        _;\n    }\n\n    function __UUPSUpgradeable_init() internal onlyInitializing {\n    }\n\n    function __UUPSUpgradeable_init_unchained() internal onlyInitializing {\n    }\n    /**\n     * @dev Implementation of the ERC-1822 {proxiableUUID} function. This returns the storage slot used by the\n     * implementation. It is used to validate the implementation's compatibility when performing an upgrade.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.\n     */\n    function proxiableUUID() external view virtual notDelegated returns (bytes32) {\n        return ERC1967Utils.IMPLEMENTATION_SLOT;\n    }\n\n    /**\n     * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call\n     * encoded in `data`.\n     *\n     * Calls {_authorizeUpgrade}.\n     *\n     * Emits an {Upgraded} event.\n     *\n     * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {\n        _authorizeUpgrade(newImplementation);\n        _upgradeToAndCallUUPS(newImplementation, data);\n    }\n\n    /**\n     * @dev Reverts if the execution is not performed via delegatecall or the execution\n     * context is not of a proxy with an ERC-1967 compliant implementation pointing to self.\n     * See {_onlyProxy}.\n     */\n    function _checkProxy() internal view virtual {\n        if (\n            address(this) == __self || // Must be called through delegatecall\n            ERC1967Utils.getImplementation() != __self // Must be called through an active proxy\n        ) {\n            revert UUPSUnauthorizedCallContext();\n        }\n    }\n\n    /**\n     * @dev Reverts if the execution is performed via delegatecall.\n     * See {notDelegated}.\n     */\n    function _checkNotDelegated() internal view virtual {\n        if (address(this) != __self) {\n            // Must not be called through delegatecall\n            revert UUPSUnauthorizedCallContext();\n        }\n    }\n\n    /**\n     * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by\n     * {upgradeToAndCall}.\n     *\n     * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.\n     *\n     * ```solidity\n     * function _authorizeUpgrade(address) internal onlyOwner {}\n     * ```\n     */\n    function _authorizeUpgrade(address newImplementation) internal virtual;\n\n    /**\n     * @dev Performs an implementation upgrade with a security check for UUPS proxies, and additional setup call.\n     *\n     * As a security check, {proxiableUUID} is invoked in the new implementation, and the return value\n     * is expected to be the implementation slot in ERC-1967.\n     *\n     * Emits an {IERC1967-Upgraded} event.\n     */\n    function _upgradeToAndCallUUPS(address newImplementation, bytes memory data) private {\n        try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {\n            if (slot != ERC1967Utils.IMPLEMENTATION_SLOT) {\n                revert UUPSUnsupportedProxiableUUID(slot);\n            }\n            ERC1967Utils.upgradeToAndCall(newImplementation, data);\n        } catch {\n            // The implementation is not UUPS\n            revert ERC1967Utils.ERC1967InvalidImplementation(newImplementation);\n        }\n    }\n}\n"},"@openzeppelin/contracts/interfaces/draft-IERC1822.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev ERC-1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified\n * proxy whose upgrades are fully controlled by the current implementation.\n */\ninterface IERC1822Proxiable {\n    /**\n     * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation\n     * address.\n     *\n     * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks\n     * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this\n     * function revert if invoked through a proxy.\n     */\n    function proxiableUUID() external view returns (bytes32);\n}\n"},"@openzeppelin/contracts/interfaces/IERC1967.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1967.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.\n */\ninterface IERC1967 {\n    /**\n     * @dev Emitted when the implementation is upgraded.\n     */\n    event Upgraded(address indexed implementation);\n\n    /**\n     * @dev Emitted when the admin account has changed.\n     */\n    event AdminChanged(address previousAdmin, address newAdmin);\n\n    /**\n     * @dev Emitted when the beacon is changed.\n     */\n    event BeaconUpgraded(address indexed beacon);\n}\n"},"@openzeppelin/contracts/proxy/beacon/IBeacon.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/beacon/IBeacon.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev This is the interface that {BeaconProxy} expects of its beacon.\n */\ninterface IBeacon {\n    /**\n     * @dev Must return an address that can be used as a delegate call target.\n     *\n     * {UpgradeableBeacon} will check that this address is a contract.\n     */\n    function implementation() external view returns (address);\n}\n"},"@openzeppelin/contracts/proxy/ERC1967/ERC1967Utils.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (proxy/ERC1967/ERC1967Utils.sol)\n\npragma solidity ^0.8.21;\n\nimport {IBeacon} from \"../beacon/IBeacon.sol\";\nimport {IERC1967} from \"../../interfaces/IERC1967.sol\";\nimport {Address} from \"../../utils/Address.sol\";\nimport {StorageSlot} from \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This library provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[ERC-1967] slots.\n */\nlibrary ERC1967Utils {\n    /**\n     * @dev Storage slot with the address of the current implementation.\n     * This is the keccak-256 hash of \"eip1967.proxy.implementation\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n\n    /**\n     * @dev The `implementation` of the proxy is invalid.\n     */\n    error ERC1967InvalidImplementation(address implementation);\n\n    /**\n     * @dev The `admin` of the proxy is invalid.\n     */\n    error ERC1967InvalidAdmin(address admin);\n\n    /**\n     * @dev The `beacon` of the proxy is invalid.\n     */\n    error ERC1967InvalidBeacon(address beacon);\n\n    /**\n     * @dev An upgrade function sees `msg.value > 0` that may be lost.\n     */\n    error ERC1967NonPayable();\n\n    /**\n     * @dev Returns the current implementation address.\n     */\n    function getImplementation() internal view returns (address) {\n        return StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the ERC-1967 implementation slot.\n     */\n    function _setImplementation(address newImplementation) private {\n        if (newImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(newImplementation);\n        }\n        StorageSlot.getAddressSlot(IMPLEMENTATION_SLOT).value = newImplementation;\n    }\n\n    /**\n     * @dev Performs implementation upgrade with additional setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-Upgraded} event.\n     */\n    function upgradeToAndCall(address newImplementation, bytes memory data) internal {\n        _setImplementation(newImplementation);\n        emit IERC1967.Upgraded(newImplementation);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(newImplementation, data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Storage slot with the admin of the contract.\n     * This is the keccak-256 hash of \"eip1967.proxy.admin\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;\n\n    /**\n     * @dev Returns the current admin.\n     *\n     * TIP: To get this value clients can read directly from the storage slot shown below (specified by ERC-1967) using\n     * the https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.\n     * `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`\n     */\n    function getAdmin() internal view returns (address) {\n        return StorageSlot.getAddressSlot(ADMIN_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new address in the ERC-1967 admin slot.\n     */\n    function _setAdmin(address newAdmin) private {\n        if (newAdmin == address(0)) {\n            revert ERC1967InvalidAdmin(address(0));\n        }\n        StorageSlot.getAddressSlot(ADMIN_SLOT).value = newAdmin;\n    }\n\n    /**\n     * @dev Changes the admin of the proxy.\n     *\n     * Emits an {IERC1967-AdminChanged} event.\n     */\n    function changeAdmin(address newAdmin) internal {\n        emit IERC1967.AdminChanged(getAdmin(), newAdmin);\n        _setAdmin(newAdmin);\n    }\n\n    /**\n     * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.\n     * This is the keccak-256 hash of \"eip1967.proxy.beacon\" subtracted by 1.\n     */\n    // solhint-disable-next-line private-vars-leading-underscore\n    bytes32 internal constant BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;\n\n    /**\n     * @dev Returns the current beacon.\n     */\n    function getBeacon() internal view returns (address) {\n        return StorageSlot.getAddressSlot(BEACON_SLOT).value;\n    }\n\n    /**\n     * @dev Stores a new beacon in the ERC-1967 beacon slot.\n     */\n    function _setBeacon(address newBeacon) private {\n        if (newBeacon.code.length == 0) {\n            revert ERC1967InvalidBeacon(newBeacon);\n        }\n\n        StorageSlot.getAddressSlot(BEACON_SLOT).value = newBeacon;\n\n        address beaconImplementation = IBeacon(newBeacon).implementation();\n        if (beaconImplementation.code.length == 0) {\n            revert ERC1967InvalidImplementation(beaconImplementation);\n        }\n    }\n\n    /**\n     * @dev Change the beacon and trigger a setup call if data is nonempty.\n     * This function is payable only if the setup call is performed, otherwise `msg.value` is rejected\n     * to avoid stuck value in the contract.\n     *\n     * Emits an {IERC1967-BeaconUpgraded} event.\n     *\n     * CAUTION: Invoking this function has no effect on an instance of {BeaconProxy} since v5, since\n     * it uses an immutable beacon without looking at the value of the ERC-1967 beacon slot for\n     * efficiency.\n     */\n    function upgradeBeaconToAndCall(address newBeacon, bytes memory data) internal {\n        _setBeacon(newBeacon);\n        emit IERC1967.BeaconUpgraded(newBeacon);\n\n        if (data.length > 0) {\n            Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);\n        } else {\n            _checkNonPayable();\n        }\n    }\n\n    /**\n     * @dev Reverts if `msg.value` is not zero. It can be used to avoid `msg.value` stuck in the contract\n     * if an upgrade doesn't perform an initialization call.\n     */\n    function _checkNonPayable() private {\n        if (msg.value > 0) {\n            revert ERC1967NonPayable();\n        }\n    }\n}\n"},"@openzeppelin/contracts/utils/Address.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\nimport {Errors} from \"./Errors.sol\";\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev There's no code at `target` (it is not a contract).\n     */\n    error AddressEmptyCode(address target);\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        if (address(this).balance < amount) {\n            revert Errors.InsufficientBalance(address(this).balance, amount);\n        }\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        if (!success) {\n            revert Errors.FailedCall();\n        }\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason or custom error, it is bubbled\n     * up by this function (like regular Solidity function calls). However, if\n     * the call reverted with no returned reason, this function reverts with a\n     * {Errors.FailedCall} error.\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        if (address(this).balance < value) {\n            revert Errors.InsufficientBalance(address(this).balance, value);\n        }\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\n     * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case\n     * of an unsuccessful call.\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata\n    ) internal view returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            // only check if target is a contract if the call was successful and the return data is empty\n            // otherwise we already know that it was a contract\n            if (returndata.length == 0 && target.code.length == 0) {\n                revert AddressEmptyCode(target);\n            }\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\n     * revert reason or with a default {Errors.FailedCall} error.\n     */\n    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\n        if (!success) {\n            _revert(returndata);\n        } else {\n            return returndata;\n        }\n    }\n\n    /**\n     * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.\n     */\n    function _revert(bytes memory returndata) private pure {\n        // Look for revert reason and bubble it up if present\n        if (returndata.length > 0) {\n            // The easiest way to bubble the revert reason is using memory via assembly\n            assembly (\"memory-safe\") {\n                let returndata_size := mload(returndata)\n                revert(add(32, returndata), returndata_size)\n            }\n        } else {\n            revert Errors.FailedCall();\n        }\n    }\n}\n"},"@openzeppelin/contracts/utils/Errors.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of common custom errors used in multiple contracts\n *\n * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.\n * It is recommended to avoid relying on the error API for critical functionality.\n *\n * _Available since v5.1._\n */\nlibrary Errors {\n    /**\n     * @dev The ETH balance of the account is not enough to perform the operation.\n     */\n    error InsufficientBalance(uint256 balance, uint256 needed);\n\n    /**\n     * @dev A call to an address target failed. The target may have reverted.\n     */\n    error FailedCall();\n\n    /**\n     * @dev The deployment failed.\n     */\n    error FailedDeployment();\n\n    /**\n     * @dev A necessary precompile is missing.\n     */\n    error MissingPrecompile(address);\n}\n"},"@openzeppelin/contracts/utils/StorageSlot.sol":{"content":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.1.0) (utils/StorageSlot.sol)\n// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Library for reading and writing primitive types to specific storage slots.\n *\n * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.\n * This library helps with reading and writing to such slots without the need for inline assembly.\n *\n * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.\n *\n * Example usage to set ERC-1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\n *     // Define the slot. Alternatively, use the SlotDerivation library to derive the slot.\n *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;\n *\n *     function _getImplementation() internal view returns (address) {\n *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;\n *     }\n *\n *     function _setImplementation(address newImplementation) internal {\n *         require(newImplementation.code.length > 0);\n *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;\n *     }\n * }\n * ```\n *\n * TIP: Consider using this library along with {SlotDerivation}.\n */\nlibrary StorageSlot {\n    struct AddressSlot {\n        address value;\n    }\n\n    struct BooleanSlot {\n        bool value;\n    }\n\n    struct Bytes32Slot {\n        bytes32 value;\n    }\n\n    struct Uint256Slot {\n        uint256 value;\n    }\n\n    struct Int256Slot {\n        int256 value;\n    }\n\n    struct StringSlot {\n        string value;\n    }\n\n    struct BytesSlot {\n        bytes value;\n    }\n\n    /**\n     * @dev Returns an `AddressSlot` with member `value` located at `slot`.\n     */\n    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BooleanSlot` with member `value` located at `slot`.\n     */\n    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Bytes32Slot` with member `value` located at `slot`.\n     */\n    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Uint256Slot` with member `value` located at `slot`.\n     */\n    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `Int256Slot` with member `value` located at `slot`.\n     */\n    function getInt256Slot(bytes32 slot) internal pure returns (Int256Slot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns a `StringSlot` with member `value` located at `slot`.\n     */\n    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.\n     */\n    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n\n    /**\n     * @dev Returns a `BytesSlot` with member `value` located at `slot`.\n     */\n    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := slot\n        }\n    }\n\n    /**\n     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.\n     */\n    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {\n        assembly (\"memory-safe\") {\n            r.slot := store.slot\n        }\n    }\n}\n"},"contracts/core/AccessController.sol":{"content":"// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.23;\r\n\r\nimport '@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol';\r\nimport '../interfaces/access/IAccessController.sol';\r\nimport '../errors/ISystemErrors.sol';\r\nimport '../events/ISystemEvents.sol';\r\n\r\n/**\r\n * @title Access Controller\r\n * @author ZeUSD Protocol Team\r\n * @notice Role-based access control system with integrated role management\r\n * @dev Implements UUPS upgradeable pattern and ERC7201 storage pattern\r\n * @custom:security-contact paras@zoth.io\r\n *\r\n * Core Features:\r\n * - Role management and assignment\r\n * - Role hierarchies and admin relationships\r\n * - Complete role membership tracking\r\n * - Configurable role properties\r\n *\r\n * Role Properties:\r\n * - Revocable: Can be removed (required for non-admin roles)\r\n * - Transferable: Can be transferred between accounts\r\n * - Expirable: Has time-based expiration\r\n *\r\n * Security Considerations:\r\n * - Only role admins can grant/revoke roles\r\n * - Role configurations protected\r\n * - Protected upgrade mechanism\r\n * - Proper storage isolation\r\n * - Role initialization validation\r\n *\r\n * Storage Layout (ERC7201):\r\n * - Roles mapping\r\n * - Role admin assignments\r\n * - Role configurations\r\n * - Role members tracking\r\n * - Initialization status\r\n */\r\ncontract AccessController is\r\n    IAccessController,\r\n    ISystemErrors,\r\n    ISystemEvents,\r\n    Initializable,\r\n    UUPSUpgradeable\r\n{\r\n    /// @custom:storage-location erc7201:access.controller.storage\r\n    struct AccessControlStorage {\r\n        /// @notice Role assignments mapping\r\n        /// @dev role hash => address => has role\r\n        mapping(bytes32 => mapping(address => bool)) roles;\r\n        /// @notice Role admin assignments\r\n        /// @dev role hash => admin role hash\r\n        mapping(bytes32 => bytes32) roleAdmin;\r\n        /// @notice Role configurations\r\n        /// @dev role hash => role configuration\r\n        mapping(bytes32 => SystemRoles.RoleConfig) roleConfigs;\r\n        /// @notice Role members list\r\n        /// @dev role hash => array of addresses\r\n        mapping(bytes32 => address[]) roleMembers;\r\n        /// @notice Initialized roles tracking\r\n        /// @dev role hash => is initialized\r\n        mapping(bytes32 => bool) initializedRoles;\r\n    }\r\n\r\n    /// @notice Storage location for ERC7201 storage pattern\r\n    /// @dev keccak256(abi.encode(uint256(keccak256(\"access.controller.storage\")) - 1)) & ~bytes32(uint256(0xff))\r\n    bytes32 private constant STORAGE_LOCATION =\r\n        0x25468c5ce048c6b29280520ac6d8964887bc20f06fd0fcbabfcb1104dfabc200;\r\n\r\n    /**\r\n     * @notice Gets storage reference using ERC7201 pattern\r\n     * @dev Uses assembly for storage slot computation\r\n     * @return $ Storage pointer to AccessControlStorage\r\n     * @custom:security Critical storage access function\r\n     */\r\n    function _getStorage() private pure returns (AccessControlStorage storage $) {\r\n        bytes32 location = STORAGE_LOCATION;\r\n        assembly {\r\n            $.slot := location\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @notice Prevents implementation contract initialization\r\n     * @dev Required for UUPS pattern security\r\n     * @custom:oz-upgrades-unsafe-allow constructor\r\n     */\r\n    constructor() {\r\n        _disableInitializers();\r\n    }\r\n\r\n    /**\r\n     * @notice Initializes the access control system\r\n     * @dev Sets up initial admin and system roles\r\n     * @param admin Address to receive initial roles\r\n     * @custom:security Only callable once\r\n     * @custom:emits RoleGranted for admin roles\r\n     */\r\n    function initialize(address admin) external initializer {\r\n        if (admin == address(0)) revert InvalidAddress(address(0));\r\n\r\n        __UUPSUpgradeable_init();\r\n\r\n        AccessControlStorage storage $ = _getStorage();\r\n\r\n        // Initialize DEFAULT_ADMIN_ROLE first\r\n        _initializeRole(\r\n            SystemRoles.DEFAULT_ADMIN_ROLE,\r\n            SystemRoles.getDefaultAdminConfig(),\r\n            SystemRoles.DEFAULT_ADMIN_ROLE\r\n        );\r\n\r\n        // Set up initial admin\r\n        $.roles[SystemRoles.DEFAULT_ADMIN_ROLE][admin] = true;\r\n        $.roleMembers[SystemRoles.DEFAULT_ADMIN_ROLE].push(admin);\r\n        emit RoleGranted(SystemRoles.DEFAULT_ADMIN_ROLE, admin, address(0));\r\n\r\n        // Initialize all other roles with DEFAULT_ADMIN_ROLE as admin\r\n        _initializeRole(\r\n            SystemRoles.UPGRADER_ROLE,\r\n            SystemRoles.getUpgraderConfig(),\r\n            SystemRoles.DEFAULT_ADMIN_ROLE\r\n        );\r\n        _initializeRole(\r\n            SystemRoles.EMERGENCY_ROLE,\r\n            SystemRoles.getEmergencyConfig(),\r\n            SystemRoles.DEFAULT_ADMIN_ROLE\r\n        );\r\n        _initializeRole(\r\n            SystemRoles.WITHDRAWAL_MANAGER_ROLE,\r\n            SystemRoles.getWithdrawalManagerConfig(),\r\n            SystemRoles.DEFAULT_ADMIN_ROLE\r\n        );\r\n        _initializeRole(\r\n            SystemRoles.VAULT_ADMIN_ROLE,\r\n            SystemRoles.getVaultAdminConfig(),\r\n            SystemRoles.DEFAULT_ADMIN_ROLE\r\n        );\r\n        _initializeRole(\r\n            SystemRoles.ASSET_MANAGER_ROLE,\r\n            SystemRoles.getAssetManagerConfig(),\r\n            SystemRoles.DEFAULT_ADMIN_ROLE\r\n        );\r\n        _initializeRole(\r\n            SystemRoles.RISK_CONTROLLER_ROLE,\r\n            SystemRoles.getRiskControllerConfig(),\r\n            SystemRoles.DEFAULT_ADMIN_ROLE\r\n        );\r\n        _initializeRole(\r\n            SystemRoles.LIQUIDATOR_ROLE,\r\n            SystemRoles.getLiquidatorConfig(),\r\n            SystemRoles.DEFAULT_ADMIN_ROLE\r\n        );\r\n        _initializeRole(\r\n            SystemRoles.PRICE_ADMIN_ROLE,\r\n            SystemRoles.getPriceAdminConfig(),\r\n            SystemRoles.DEFAULT_ADMIN_ROLE\r\n        );\r\n        _initializeRole(\r\n            SystemRoles.REWARD_MANAGER_ROLE,\r\n            SystemRoles.getRewardManagerConfig(),\r\n            SystemRoles.DEFAULT_ADMIN_ROLE\r\n        );\r\n\r\n        // Grant all roles to admin\r\n        $.roles[SystemRoles.UPGRADER_ROLE][admin] = true;\r\n        $.roles[SystemRoles.EMERGENCY_ROLE][admin] = true;\r\n        $.roles[SystemRoles.WITHDRAWAL_MANAGER_ROLE][admin] = true;\r\n        $.roles[SystemRoles.VAULT_ADMIN_ROLE][admin] = true;\r\n        $.roles[SystemRoles.ASSET_MANAGER_ROLE][admin] = true;\r\n        $.roles[SystemRoles.RISK_CONTROLLER_ROLE][admin] = true;\r\n        $.roles[SystemRoles.LIQUIDATOR_ROLE][admin] = true;\r\n        $.roles[SystemRoles.PRICE_ADMIN_ROLE][admin] = true;\r\n        $.roles[SystemRoles.REWARD_MANAGER_ROLE][admin] = true;\r\n\r\n        // Add admin to role members lists\r\n        $.roleMembers[SystemRoles.UPGRADER_ROLE].push(admin);\r\n        $.roleMembers[SystemRoles.EMERGENCY_ROLE].push(admin);\r\n        $.roleMembers[SystemRoles.WITHDRAWAL_MANAGER_ROLE].push(admin);\r\n        $.roleMembers[SystemRoles.VAULT_ADMIN_ROLE].push(admin);\r\n        $.roleMembers[SystemRoles.ASSET_MANAGER_ROLE].push(admin);\r\n        $.roleMembers[SystemRoles.RISK_CONTROLLER_ROLE].push(admin);\r\n        $.roleMembers[SystemRoles.LIQUIDATOR_ROLE].push(admin);\r\n        $.roleMembers[SystemRoles.PRICE_ADMIN_ROLE].push(admin);\r\n        $.roleMembers[SystemRoles.REWARD_MANAGER_ROLE].push(admin);\r\n\r\n        // Emit events for all role grants\r\n        emit RoleGranted(SystemRoles.UPGRADER_ROLE, admin, address(0));\r\n        emit RoleGranted(SystemRoles.EMERGENCY_ROLE, admin, address(0));\r\n        emit RoleGranted(SystemRoles.WITHDRAWAL_MANAGER_ROLE, admin, address(0));\r\n        emit RoleGranted(SystemRoles.VAULT_ADMIN_ROLE, admin, address(0));\r\n        emit RoleGranted(SystemRoles.ASSET_MANAGER_ROLE, admin, address(0));\r\n        emit RoleGranted(SystemRoles.RISK_CONTROLLER_ROLE, admin, address(0));\r\n        emit RoleGranted(SystemRoles.LIQUIDATOR_ROLE, admin, address(0));\r\n        emit RoleGranted(SystemRoles.PRICE_ADMIN_ROLE, admin, address(0));\r\n        emit RoleGranted(SystemRoles.REWARD_MANAGER_ROLE, admin, address(0));\r\n    }\r\n\r\n    /**\r\n     * @notice Initialize a new role\r\n     * @param role Role identifier\r\n     * @param config Role configuration\r\n     * @param adminRole Admin role\r\n     * @custom:security Only DEFAULT_ADMIN_ROLE can initialize roles\r\n     * @custom:emits RoleAdminChanged\r\n     */\r\n    function initializeRole(\r\n        bytes32 role,\r\n        SystemRoles.RoleConfig memory config,\r\n        bytes32 adminRole\r\n    ) external {\r\n        AccessControlStorage storage $ = _getStorage();\r\n        if (!$.roles[SystemRoles.DEFAULT_ADMIN_ROLE][msg.sender]) {\r\n            revert Unauthorized('Not admin');\r\n        }\r\n\r\n        _initializeRole(role, config, adminRole);\r\n    }\r\n\r\n    /**\r\n     * @notice Internal function to initialize role\r\n     * @param role Role identifier\r\n     * @param config Role configuration\r\n     * @param adminRole Admin role\r\n     * @custom:security Validates role configuration\r\n     */\r\n    function _initializeRole(\r\n        bytes32 role,\r\n        SystemRoles.RoleConfig memory config,\r\n        bytes32 adminRole\r\n    ) private {\r\n        AccessControlStorage storage $ = _getStorage();\r\n\r\n        if ($.initializedRoles[role]) revert InvalidRole(role);\r\n        if (!config.revocable && role != SystemRoles.DEFAULT_ADMIN_ROLE) {\r\n            revert InvalidConfig('Non-admin roles must be revocable');\r\n        }\r\n\r\n        $.roleConfigs[role] = config;\r\n        $.roleAdmin[role] = adminRole;\r\n        $.initializedRoles[role] = true;\r\n\r\n        emit RoleAdminChanged(role, bytes32(0), adminRole);\r\n    }\r\n\r\n    /**\r\n     * @notice Grants a role to an account\r\n     * @param role Role to grant\r\n     * @param account Account to receive role\r\n     * @custom:security Only role admin can grant roles\r\n     * @custom:emits RoleGranted\r\n     */\r\n    function grantRole(bytes32 role, address account) external override {\r\n        AccessControlStorage storage $ = _getStorage();\r\n\r\n        if (!$.initializedRoles[role]) revert InvalidRole(role);\r\n        if (!$.roles[$.roleAdmin[role]][msg.sender]) {\r\n            revert Unauthorized('Not role admin');\r\n        }\r\n\r\n        if (account == address(0)) revert InvalidAddress(address(0));\r\n        if ($.roles[role][account]) return; // Already has role\r\n\r\n        $.roles[role][account] = true;\r\n        $.roleMembers[role].push(account);\r\n\r\n        emit RoleGranted(role, account, msg.sender);\r\n    }\r\n\r\n    /**\r\n     * @notice Revokes a role from an account\r\n     * @param role Role to revoke\r\n     * @param account Account to revoke from\r\n     * @custom:security Only role admin can revoke roles\r\n     * @custom:emits RoleRevoked\r\n     */\r\n    function revokeRole(bytes32 role, address account) external override {\r\n        AccessControlStorage storage $ = _getStorage();\r\n\r\n        if (!$.initializedRoles[role]) revert InvalidRole(role);\r\n        if (!$.roles[$.roleAdmin[role]][msg.sender]) {\r\n            revert Unauthorized('Not role admin');\r\n        }\r\n\r\n        SystemRoles.RoleConfig memory config = $.roleConfigs[role];\r\n        if (!config.revocable) revert OperationFailed('Role not revocable');\r\n\r\n        if (!$.roles[role][account]) return;\r\n\r\n        $.roles[role][account] = false;\r\n        _removeRoleMember(role, account);\r\n\r\n        emit RoleRevoked(role, account, msg.sender);\r\n    }\r\n\r\n    /**\r\n     * @notice Gets role configuration\r\n     * @param role Role identifier\r\n     * @return RoleConfig Role configuration\r\n     */\r\n    function getRoleConfig(\r\n        bytes32 role\r\n    ) external view override returns (SystemRoles.RoleConfig memory) {\r\n        AccessControlStorage storage $ = _getStorage();\r\n        if (!$.initializedRoles[role]) revert InvalidRole(role);\r\n        return $.roleConfigs[role];\r\n    }\r\n\r\n    /**\r\n     * @notice Gets admin role\r\n     * @param role Role to check\r\n     * @return bytes32 Admin role\r\n     */\r\n    function getRoleAdmin(bytes32 role) external view returns (bytes32) {\r\n        AccessControlStorage storage $ = _getStorage();\r\n        if (!$.initializedRoles[role]) revert InvalidRole(role);\r\n        return $.roleAdmin[role];\r\n    }\r\n\r\n    /**\r\n     * @notice Sets admin role\r\n     * @param role Role to modify\r\n     * @param adminRole New admin role\r\n     * @custom:security Only DEFAULT_ADMIN_ROLE can change role admins\r\n     * @custom:emits RoleAdminChanged\r\n     */\r\n    function setRoleAdmin(bytes32 role, bytes32 adminRole) external {\r\n        AccessControlStorage storage $ = _getStorage();\r\n        if (!$.roles[SystemRoles.DEFAULT_ADMIN_ROLE][msg.sender]) {\r\n            revert Unauthorized('Not admin');\r\n        }\r\n\r\n        if (!$.initializedRoles[role]) revert InvalidRole(role);\r\n        if (!$.initializedRoles[adminRole]) revert InvalidRole(adminRole);\r\n\r\n        bytes32 previousAdmin = $.roleAdmin[role];\r\n        $.roleAdmin[role] = adminRole;\r\n\r\n        emit RoleAdminChanged(role, previousAdmin, adminRole);\r\n    }\r\n\r\n    /**\r\n     * @notice Checks if an account has a role\r\n     * @param role Role to check\r\n     * @param account Account to check\r\n     * @return bool True if account has role\r\n     */\r\n    function hasRole(bytes32 role, address account) external view override returns (bool) {\r\n        return _getStorage().roles[role][account];\r\n    }\r\n\r\n    /**\r\n     * @notice Gets role members\r\n     * @param role Role to check\r\n     * @return address[] Array of role members\r\n     */\r\n    function getRoleMembers(bytes32 role) external view returns (address[] memory) {\r\n        AccessControlStorage storage $ = _getStorage();\r\n        if (!$.initializedRoles[role]) revert InvalidRole(role);\r\n        return $.roleMembers[role];\r\n    }\r\n\r\n    /**\r\n     * @notice Checks if role is initialized\r\n     * @param role Role to check\r\n     * @return bool True if initialized\r\n     */\r\n    function isRoleInitialized(bytes32 role) external view returns (bool) {\r\n        return _getStorage().initializedRoles[role];\r\n    }\r\n\r\n    /**\r\n     * @notice Internal helper to remove role member\r\n     * @param role Role to modify\r\n     * @param account Account to remove\r\n     */\r\n    function _removeRoleMember(bytes32 role, address account) private {\r\n        address[] storage members = _getStorage().roleMembers[role];\r\n        for (uint i = 0; i < members.length; i++) {\r\n            if (members[i] == account) {\r\n                members[i] = members[members.length - 1];\r\n                members.pop();\r\n                break;\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @notice Authorizes contract upgrade\r\n     * @param newImplementation Address of new implementation\r\n     */\r\n    function _authorizeUpgrade(address newImplementation) internal override {\r\n        if (!_getStorage().roles[SystemRoles.UPGRADER_ROLE][msg.sender]) {\r\n            revert Unauthorized('Not upgrader');\r\n        }\r\n    }\r\n}\r\n"},"contracts/errors/ISystemErrors.sol":{"content":"// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.23;\r\n\r\n/**\r\n * @title System Errors Interface\r\n * @author ZeUSD Protocol Team\r\n * @notice Defines standard error types used across the protocol\r\n * @dev Interface containing common error definitions\r\n */\r\ninterface ISystemErrors {\r\n    /**\r\n     * @notice Error thrown for invalid address inputs\r\n     * @param addr The invalid address\r\n     */\r\n    error InvalidAddress(address addr);\r\n\r\n    /**\r\n     * @notice Error thrown for unauthorized operations\r\n     * @param message Error description\r\n     */\r\n    error Unauthorized(string message);\r\n\r\n    /**\r\n     * @notice Error thrown for invalid role operations\r\n     * @param role Role identifier that caused the error\r\n     */\r\n    error InvalidRole(bytes32 role);\r\n\r\n    /**\r\n     * @notice Error thrown for invalid configuration parameters\r\n     * @param message Error description\r\n     */\r\n    error InvalidConfig(string message);\r\n\r\n    /**\r\n     * @notice Error thrown when an operation fails\r\n     * @param message Error description\r\n     */\r\n    error OperationFailed(string message);\r\n\r\n    /**\r\n     * @notice Error thrown for invalid array lengths in batch operations\r\n     */\r\n    error InvalidArrayLength();\r\n\r\n    /**\r\n     * @notice Error thrown when router is not properly set\r\n     * @param message Error description\r\n     */\r\n    error RouterNotSet(string message);\r\n\r\n    /**\r\n     * @notice Error thrown when caller is not the router\r\n     * @param message Error description\r\n     */\r\n    error NotRouter(string message);\r\n\r\n    /**\r\n     * @notice Error thrown for initial approval issues\r\n     * @param message Error description\r\n     */\r\n    error InitialApproval(string message);\r\n\r\n    /**\r\n     * @notice Error thrown when contract not found in registry\r\n     * @param id Contract identifier\r\n     */\r\n    error ContractNotFound(bytes32 id);\r\n\r\n    /**\r\n     * @notice Error thrown when trying to grant a role to the zero address\r\n     */\r\n    error ZeroAddress();\r\n\r\n    /**\r\n     * @notice Error thrown when version doesn't match expected\r\n     * @param expected Expected version\r\n     * @param actual Actual version\r\n     */\r\n    error InvalidVersion(uint256 expected, uint256 actual);\r\n\r\n    /**\r\n     * @notice Error thrown when contract already exists in registry\r\n     * @param id Contract identifier\r\n     */\r\n    error ContractExists(bytes32 id);\r\n}\r\n"},"contracts/events/ISystemEvents.sol":{"content":"// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.23;\r\n\r\n/**\r\n * @title System Events Interface\r\n * @author ZeUSD Protocol Team\r\n * @notice Defines core system events emitted across the protocol\r\n * @dev Interface containing common event definitions\r\n */\r\ninterface ISystemEvents {\r\n    /**\r\n     * @notice Emitted when a contract address is updated\r\n     * @param id Contract identifier\r\n     * @param oldAddr Previous contract address\r\n     * @param newAddr New contract address\r\n     * @param version New version number\r\n     */\r\n    event ContractAddressUpdated(\r\n        bytes32 indexed id,\r\n        address indexed oldAddr,\r\n        address indexed newAddr,\r\n        uint256 version\r\n    );\r\n    /**\r\n     * @notice Emitted when a role is granted to an account\r\n     * @param role The role that was granted\r\n     * @param account The account that received the role\r\n     * @param sender The account that granted the role\r\n     */\r\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\r\n\r\n    /**\r\n     * @notice Emitted when a role is revoked from an account\r\n     * @param role The role that was revoked\r\n     * @param account The account that lost the role\r\n     * @param sender The account that revoked the role\r\n     */\r\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\r\n\r\n    /**\r\n     * @notice Emitted when a role's admin role is changed\r\n     * @param role The role that was affected\r\n     * @param previousAdminRole The old admin role\r\n     * @param newAdminRole The new admin role\r\n     */\r\n    event RoleAdminChanged(\r\n        bytes32 indexed role,\r\n        bytes32 indexed previousAdminRole,\r\n        bytes32 indexed newAdminRole\r\n    );\r\n\r\n    /**\r\n     * @notice Emitted when contract addresses are updated\r\n     * @param collateralVault New collateral vault address\r\n     * @param zeusdToken New ZeUSD token address\r\n     * @param lzAdapter New LayerZero adapter address\r\n     */\r\n    event AddressesUpdated(\r\n        address indexed collateralVault,\r\n        address indexed zeusdToken,\r\n        address indexed lzAdapter\r\n    );\r\n\r\n    /**\r\n     * @notice Emitted when contract is upgraded\r\n     * @param implementation New implementation address\r\n     */\r\n    event Upgraded(address indexed implementation);\r\n\r\n    /**\r\n     * @notice Emitted when a contract is registered\r\n     * @param id Contract identifier\r\n     * @param addr Contract address\r\n     * @param version Contract version\r\n     */\r\n    event ContractRegistered(bytes32 indexed id, address indexed addr, uint256 version);\r\n\r\n    /**\r\n     * @notice Emitted when a contract is updated\r\n     * @param id Contract identifier\r\n     * @param oldAddr Previous contract address\r\n     * @param newAddr New contract address\r\n     * @param version New version number\r\n     */\r\n    event ContractUpdated(\r\n        bytes32 indexed id,\r\n        address indexed oldAddr,\r\n        address indexed newAddr,\r\n        uint256 version\r\n    );\r\n}\r\n"},"contracts/interfaces/access/IAccessController.sol":{"content":"// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.23;\r\n\r\nimport '../../libraries/SystemRoles.sol';\r\n\r\n/**\r\n * @title Access Controller Interface\r\n * @author ZeUSD Protocol Team\r\n * @notice Interface for managing role-based access control across the protocol\r\n * @dev Combines standard role management with custom role configuration\r\n * @custom:security-contact paras@zoth.io\r\n */\r\ninterface IAccessController {\r\n    /**\r\n     * @notice Checks if an account has a specific role\r\n     * @param role Role identifier to check\r\n     * @param account Account to verify\r\n     * @return bool True if account has the role\r\n     * @dev Core function for role verification\r\n     */\r\n    function hasRole(bytes32 role, address account) external view returns (bool);\r\n\r\n    /**\r\n     * @notice Grants a role to an account\r\n     * @param role Role to grant\r\n     * @param account Account to receive the role\r\n     * @dev Only callable by role admin\r\n     */\r\n    function grantRole(bytes32 role, address account) external;\r\n\r\n    /**\r\n     * @notice Revokes a role from an account\r\n     * @param role Role to revoke\r\n     * @param account Account to revoke from\r\n     * @dev Only callable by role admin\r\n     */\r\n    function revokeRole(bytes32 role, address account) external;\r\n\r\n    /**\r\n     * @notice Gets configuration for a specific role\r\n     * @param role Role identifier\r\n     * @return RoleConfig Configuration struct for the role\r\n     * @dev Returns role settings and constraints\r\n     */\r\n    function getRoleConfig(bytes32 role) external view returns (SystemRoles.RoleConfig memory);\r\n\r\n    /**\r\n     * @notice Initializes a new role with configuration\r\n     * @param role Role identifier to initialize\r\n     * @param config Role configuration settings\r\n     * @param adminRole Role that will administer this role\r\n     * @dev Sets up new role with specified parameters\r\n     */\r\n    function initializeRole(\r\n        bytes32 role,\r\n        SystemRoles.RoleConfig memory config,\r\n        bytes32 adminRole\r\n    ) external;\r\n\r\n    /**\r\n     * @notice Gets the admin role for a role\r\n     * @param role Role to query\r\n     * @return bytes32 Admin role identifier\r\n     * @dev Returns role that can manage the queried role\r\n     */\r\n    function getRoleAdmin(bytes32 role) external view returns (bytes32);\r\n\r\n    /**\r\n     * @notice Sets the admin role for a role\r\n     * @param role Role to modify\r\n     * @param adminRole New admin role\r\n     * @dev Changes which role can manage the specified role\r\n     */\r\n    function setRoleAdmin(bytes32 role, bytes32 adminRole) external;\r\n\r\n    /**\r\n     * @notice Gets all members with a specific role\r\n     * @param role Role to query\r\n     * @return address[] Array of addresses with the role\r\n     * @dev Returns complete list of role members\r\n     */\r\n    function getRoleMembers(bytes32 role) external view returns (address[] memory);\r\n\r\n    /**\r\n     * @notice Checks if a role has been initialized\r\n     * @param role Role to check\r\n     * @return bool True if role is initialized\r\n     * @dev Verifies role existence and setup\r\n     */\r\n    function isRoleInitialized(bytes32 role) external view returns (bool);\r\n}\r\n"},"contracts/libraries/SystemRoles.sol":{"content":"// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.23;\r\nimport '../utils/Constants.sol';\r\n\r\n/**\r\n * @title System Roles\r\n * @notice Defines roles and their configurations\r\n * @dev Uses constants from main Constants library\r\n * @author ZeUSD Protocol Team\r\n * @custom:security-contact paras@zoth.io\r\n */\r\nlibrary SystemRoles {\r\n    // Core Administrative Roles\r\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\r\n    bytes32 public constant EMERGENCY_ROLE = keccak256('EMERGENCY_ROLE');\r\n    bytes32 public constant UPGRADER_ROLE = keccak256('UPGRADER_ROLE');\r\n    bytes32 public constant WITHDRAWAL_MANAGER_ROLE = keccak256('WITHDRAWAL_MANAGER_ROLE');\r\n\r\n    // Vault Management Roles\r\n    bytes32 public constant VAULT_ADMIN_ROLE = keccak256('VAULT_ADMIN_ROLE');\r\n    bytes32 public constant ASSET_MANAGER_ROLE = keccak256('ASSET_MANAGER_ROLE');\r\n\r\n    // Risk & Control Roles\r\n    bytes32 public constant RISK_CONTROLLER_ROLE = keccak256('RISK_CONTROLLER_ROLE');\r\n    bytes32 public constant LIQUIDATOR_ROLE = keccak256('LIQUIDATOR_ROLE');\r\n    bytes32 public constant PRICE_ADMIN_ROLE = keccak256('PRICE_ADMIN_ROLE');\r\n\r\n    // Rewards & Incentives\r\n    bytes32 public constant REWARD_MANAGER_ROLE = keccak256('REWARD_MANAGER_ROLE');\r\n\r\n    /**\r\n     * @notice Role configuration data structure\r\n     * @param adminRole Role that can grant/revoke this role\r\n     * @param timelock Required delay for critical operations\r\n     * @param requiresConsensus Whether consensus is required\r\n     * @param revocable Whether role can be revoked\r\n     * @param pausable Whether role can be paused\r\n     */\r\n    struct RoleConfig {\r\n        bytes32 adminRole;\r\n        uint256 timelock;\r\n        bool requiresConsensus;\r\n        bool revocable;\r\n        bool pausable;\r\n    }\r\n\r\n    /**\r\n     * @notice Permission configuration data structure\r\n     * @param role Role identifier\r\n     * @param functionSig Function signature\r\n     * @param enabled Whether permission is active\r\n     * @param restrictions Additional restrictions (bitmap)\r\n     */\r\n    struct Permission {\r\n        bytes32 role;\r\n        bytes4 functionSig;\r\n        bool enabled;\r\n        uint256 restrictions;\r\n    }\r\n\r\n    /**\r\n     * @notice Returns DEFAULT_ADMIN_ROLE configuration\r\n     * @dev Highest authority, requires consensus and delay\r\n     */\r\n    function getDefaultAdminConfig() internal pure returns (RoleConfig memory) {\r\n        return\r\n            RoleConfig({\r\n                adminRole: DEFAULT_ADMIN_ROLE,\r\n                timelock: Constants.TWO_DAYS,\r\n                requiresConsensus: true,\r\n                revocable: false,\r\n                pausable: false\r\n            });\r\n    }\r\n\r\n    /**\r\n     * @notice Returns EMERGENCY_ROLE configuration\r\n     * @dev Quick response role, no delay but revocable\r\n     */\r\n    function getEmergencyConfig() internal pure returns (RoleConfig memory) {\r\n        return\r\n            RoleConfig({\r\n                adminRole: DEFAULT_ADMIN_ROLE,\r\n                timelock: 0,\r\n                requiresConsensus: false,\r\n                revocable: true,\r\n                pausable: true\r\n            });\r\n    }\r\n\r\n    /**\r\n     * @notice Returns UPGRADER_ROLE configuration\r\n     * @dev Contract upgrade role, requires consensus\r\n     */\r\n    function getWithdrawalManagerConfig() internal pure returns (RoleConfig memory) {\r\n        return\r\n            RoleConfig({\r\n                adminRole: DEFAULT_ADMIN_ROLE,\r\n                timelock: Constants.ONE_DAY,\r\n                requiresConsensus: true,\r\n                revocable: true,\r\n                pausable: true\r\n            });\r\n    }\r\n\r\n    /**\r\n     * @notice Returns UPGRADER_ROLE configuration\r\n     * @dev Contract upgrade role, requires consensus\r\n     */\r\n    function getUpgraderConfig() internal pure returns (RoleConfig memory) {\r\n        return\r\n            RoleConfig({\r\n                adminRole: DEFAULT_ADMIN_ROLE,\r\n                timelock: Constants.ONE_DAY,\r\n                requiresConsensus: true,\r\n                revocable: true,\r\n                pausable: true\r\n            });\r\n    }\r\n\r\n    /**\r\n     * @notice Returns VAULT_ADMIN_ROLE configuration\r\n     * @dev Vault management role with delay\r\n     */\r\n    function getVaultAdminConfig() internal pure returns (RoleConfig memory) {\r\n        return\r\n            RoleConfig({\r\n                adminRole: DEFAULT_ADMIN_ROLE,\r\n                timelock: Constants.ONE_DAY,\r\n                requiresConsensus: true,\r\n                revocable: true,\r\n                pausable: true\r\n            });\r\n    }\r\n\r\n    /**\r\n     * @notice Returns ASSET_MANAGER_ROLE configuration\r\n     * @dev Asset management under vault admin\r\n     */\r\n    function getAssetManagerConfig() internal pure returns (RoleConfig memory) {\r\n        return\r\n            RoleConfig({\r\n                adminRole: VAULT_ADMIN_ROLE,\r\n                timelock: Constants.TWELVE_HOURS,\r\n                requiresConsensus: true,\r\n                revocable: true,\r\n                pausable: true\r\n            });\r\n    }\r\n\r\n    /**\r\n     * @notice Returns RISK_CONTROLLER_ROLE configuration\r\n     * @dev Risk parameter management role\r\n     */\r\n    function getRiskControllerConfig() internal pure returns (RoleConfig memory) {\r\n        return\r\n            RoleConfig({\r\n                adminRole: DEFAULT_ADMIN_ROLE,\r\n                timelock: Constants.TWELVE_HOURS,\r\n                requiresConsensus: true,\r\n                revocable: true,\r\n                pausable: true\r\n            });\r\n    }\r\n\r\n    /**\r\n     * @notice Returns LIQUIDATOR_ROLE configuration\r\n     * @dev Liquidation execution role, no delay\r\n     */\r\n    function getLiquidatorConfig() internal pure returns (RoleConfig memory) {\r\n        return\r\n            RoleConfig({\r\n                adminRole: RISK_CONTROLLER_ROLE,\r\n                timelock: 0,\r\n                requiresConsensus: false,\r\n                revocable: true,\r\n                pausable: true\r\n            });\r\n    }\r\n\r\n    /**\r\n     * @notice Returns PRICE_ADMIN_ROLE configuration\r\n     * @dev Oracle management role\r\n     */\r\n    function getPriceAdminConfig() internal pure returns (RoleConfig memory) {\r\n        return\r\n            RoleConfig({\r\n                adminRole: DEFAULT_ADMIN_ROLE,\r\n                timelock: Constants.TWELVE_HOURS,\r\n                requiresConsensus: true,\r\n                revocable: true,\r\n                pausable: true\r\n            });\r\n    }\r\n\r\n    /**\r\n     * @notice Returns REWARD_MANAGER_ROLE configuration\r\n     * @dev Rewards management role\r\n     */\r\n    function getRewardManagerConfig() internal pure returns (RoleConfig memory) {\r\n        return\r\n            RoleConfig({\r\n                adminRole: DEFAULT_ADMIN_ROLE,\r\n                timelock: Constants.ONE_DAY,\r\n                requiresConsensus: true,\r\n                revocable: true,\r\n                pausable: true\r\n            });\r\n    }\r\n}\r\n"},"contracts/utils/Constants.sol":{"content":"// SPDX-License-Identifier: MIT\r\npragma solidity 0.8.23;\r\n\r\n/**\r\n * @title Protocol Constants\r\n * @author ZeUSD Protocol Team\r\n * @notice Central source for all protocol constants\r\n * @dev Single source of truth for contract identifiers and constants\r\n * @custom:security Constants should never be modified after deployment\r\n */\r\nlibrary Constants {\r\n    /**\r\n     * @notice Protocol Contract Identifiers\r\n     * @dev Unique identifiers for protocol contracts in registry\r\n     */\r\n    bytes32 public constant CONTRACT_ACCESS_CONTROLLER = keccak256('CONTRACT_ACCESS_CONTROLLER');\r\n    bytes32 public constant CONTRACT_REGISTRY = keccak256('CONTRACT_REGISTRY');\r\n    bytes32 public constant CONTRACT_ZEUSD = keccak256('CONTRACT_ZEUSD');\r\n    bytes32 public constant CONTRACT_ROUTER = keccak256('CONTRACT_ROUTER');\r\n    bytes32 public constant CONTRACT_TREASURY = keccak256('CONTRACT_TREASURY');\r\n    bytes32 public constant CONTRACT_ORACLE = keccak256('CONTRACT_ORACLE');\r\n    bytes32 public constant CONTRACT_DEPOSIT_NFT = keccak256('CONTRACT_DEPOSIT_NFT');\r\n    bytes32 public constant CONTRACT_WITHDRAWAL_SYSTEM = keccak256('CONTRACT_WITHDRAWAL_SYSTEM');\r\n\r\n    /**\r\n     * @notice Time Constants\r\n     * @dev Standard time periods used throughout the protocol\r\n     */\r\n    uint256 public constant ONE_HOUR = 1 hours;\r\n    uint256 public constant ONE_DAY = 1 days;\r\n    uint256 public constant ONE_WEEK = 7 days;\r\n    uint256 public constant TWO_DAYS = 2 days;\r\n    uint256 public constant TWELVE_HOURS = 12 hours;\r\n\r\n    /**\r\n     * @notice Protocol Parameters\r\n     * @dev Governance and operational limits\r\n     */\r\n    /// @notice Maximum number of roles a single account can hold\r\n    uint256 public constant MAX_ROLES_PER_ACCOUNT = 10;\r\n\r\n    /// @notice Maximum number of members that can be assigned to a role\r\n    uint256 public constant MAX_MEMBERS_PER_ROLE = 50;\r\n\r\n    /// @notice Percentage threshold required for consensus decisions (66%)\r\n    uint256 public constant CONSENSUS_THRESHOLD = 66;\r\n\r\n    /// @notice Delay period for emergency actions\r\n    uint256 public constant EMERGENCY_DELAY = 1 hours;\r\n}\r\n"}},"matchId":"21647918","creationMatch":"exact_match","runtimeMatch":"exact_match","verifiedAt":"2026-03-08T04:42:27Z","match":"exact_match","chainId":"1","address":"0xF5B1084B3F68f347A6099e3Eabb279d9e8be122b"}