ocn-registry
Version:
Oli-systems OCN registry smart contracts
99 lines • 92.3 kB
JSON
{
"language": "Solidity",
"sources": {
"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"@openzeppelin/contracts/access/IAccessControl.sol\";\nimport {ContextUpgradeable} from \"../utils/ContextUpgradeable.sol\";\nimport {ERC165Upgradeable} from \"../utils/introspection/ERC165Upgradeable.sol\";\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControlUpgradeable is Initializable, ContextUpgradeable, IAccessControl, ERC165Upgradeable {\n struct RoleData {\n mapping(address account => bool) hasRole;\n bytes32 adminRole;\n }\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n\n /// @custom:storage-location erc7201:openzeppelin.storage.AccessControl\n struct AccessControlStorage {\n mapping(bytes32 role => RoleData) _roles;\n }\n\n // keccak256(abi.encode(uint256(keccak256(\"openzeppelin.storage.AccessControl\")) - 1)) & ~bytes32(uint256(0xff))\n bytes32 private constant AccessControlStorageLocation = 0x02dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800;\n\n function _getAccessControlStorage() private pure returns (AccessControlStorage storage $) {\n assembly {\n $.slot := AccessControlStorageLocation\n }\n }\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with an {AccessControlUnauthorizedAccount} error including the required role.\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n function __AccessControl_init() internal onlyInitializing {\n }\n\n function __AccessControl_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n AccessControlStorage storage $ = _getAccessControlStorage();\n return $._roles[role].hasRole[account];\n }\n\n /**\n * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n * is missing `role`.\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert AccessControlUnauthorizedAccount(account, role);\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n AccessControlStorage storage $ = _getAccessControlStorage();\n return $._roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `callerConfirmation`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n if (callerConfirmation != _msgSender()) {\n revert AccessControlBadConfirmation();\n }\n\n _revokeRole(role, callerConfirmation);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n AccessControlStorage storage $ = _getAccessControlStorage();\n bytes32 previousAdminRole = getRoleAdmin(role);\n $._roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n AccessControlStorage storage $ = _getAccessControlStorage();\n if (!hasRole(role, account)) {\n $._roles[role].hasRole[account] = true;\n emit RoleGranted(role, account, _msgSender());\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n AccessControlStorage storage $ = _getAccessControlStorage();\n if (hasRole(role, account)) {\n $._roles[role].hasRole[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n return true;\n } else {\n return false;\n }\n }\n}\n"
},
"@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.0.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 ERC1967) 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 ERC1167 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 ERC1822 {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 ERC1967-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 ERC1967.\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-upgradeable/utils/ContextUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\nimport {Initializable} from \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n"
},
"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\nimport {Initializable} from \"../../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165Upgradeable is Initializable, IERC165 {\n function __ERC165_init() internal onlyInitializing {\n }\n\n function __ERC165_init_unchained() internal onlyInitializing {\n }\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n"
},
"@openzeppelin/contracts/access/AccessControl.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.20;\n\nimport {IAccessControl} from \"./IAccessControl.sol\";\nimport {Context} from \"../utils/Context.sol\";\nimport {ERC165} from \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address account => bool) hasRole;\n bytes32 adminRole;\n }\n\n mapping(bytes32 role => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with an {AccessControlUnauthorizedAccount} error including the required role.\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual returns (bool) {\n return _roles[role].hasRole[account];\n }\n\n /**\n * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`\n * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`\n * is missing `role`.\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert AccessControlUnauthorizedAccount(account, role);\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `callerConfirmation`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address callerConfirmation) public virtual {\n if (callerConfirmation != _msgSender()) {\n revert AccessControlBadConfirmation();\n }\n\n _revokeRole(role, callerConfirmation);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual returns (bool) {\n if (!hasRole(role, account)) {\n _roles[role].hasRole[account] = true;\n emit RoleGranted(role, account, _msgSender());\n return true;\n } else {\n return false;\n }\n }\n\n /**\n * @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {\n if (hasRole(role, account)) {\n _roles[role].hasRole[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n return true;\n } else {\n return false;\n }\n }\n}\n"
},
"@openzeppelin/contracts/access/IAccessControl.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (access/IAccessControl.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev The `account` is missing a role.\n */\n error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);\n\n /**\n * @dev The caller of a function is not the expected one.\n *\n * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.\n */\n error AccessControlBadConfirmation();\n\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `callerConfirmation`.\n */\n function renounceRole(bytes32 role, address callerConfirmation) external;\n}\n"
},
"@openzeppelin/contracts/interfaces/draft-IERC1822.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC1822.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev ERC1822: 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/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.0.0) (proxy/ERC1967/ERC1967Utils.sol)\n\npragma solidity ^0.8.20;\n\nimport {IBeacon} from \"../beacon/IBeacon.sol\";\nimport {Address} from \"../../utils/Address.sol\";\nimport {StorageSlot} from \"../../utils/StorageSlot.sol\";\n\n/**\n * @dev This abstract contract provides getters and event emitting update functions for\n * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.\n */\nlibrary ERC1967Utils {\n // We re-declare ERC-1967 events here because they can't be used directly from IERC1967.\n // This will be fixed in Solidity 0.8.21. At that point we should remove these events.\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 /**\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 EIP1967 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 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 EIP1967) 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 EIP1967 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 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 EIP1967 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 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/token/ERC20/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the value of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the value of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 value) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets a `value` amount of tokens as the allowance of `spender` over the\n * caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 value) external returns (bool);\n\n /**\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\n * allowance mechanism. `value` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 value) external returns (bool);\n}\n"
},
"@openzeppelin/contracts/utils/Address.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev The ETH balance of the account is not enough to perform the operation.\n */\n error AddressInsufficientBalance(address account);\n\n /**\n * @dev There's no code at `target` (it is not a contract).\n */\n error AddressEmptyCode(address target);\n\n /**\n * @dev A call to an address target failed. The target may have reverted.\n */\n error FailedInnerCall();\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 AddressInsufficientBalance(address(this));\n }\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n if (!success) {\n revert FailedInnerCall();\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 * {FailedInnerCall} 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 AddressInsufficientBalance(address(this));\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 {FailedInnerCall}) in case of an\n * 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 {FailedInnerCall} 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 {FailedInnerCall}.\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 /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert FailedInnerCall();\n }\n }\n}\n"
},
"@openzeppelin/contracts/utils/Context.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n function _contextSuffixLength() internal view virtual returns (uint256) {\n return 0;\n }\n}\n"
},
"@openzeppelin/contracts/utils/introspection/ERC165.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.20;\n\nimport {IERC165} from \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n"
},
"@openzeppelin/contracts/utils/introspection/IERC165.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.20;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"
},
"@openzeppelin/contracts/utils/StorageSlot.sol": {
"content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v5.0.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 ERC1967 implementation slot:\n * ```solidity\n * contract ERC1967 {\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 */\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 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 /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `BooleanSlot` with member `value` located at `slot`.\n */\n function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.\n */\n function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `Uint256Slot` with member `value` located at `slot`.\n */\n function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\n r.slot := slot\n }\n }\n\n /**\n * @dev Returns an `StringSlot` with member `value` located at `slot`.\n */\n function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\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 /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n\n /**\n * @dev Returns an `BytesSlot` with member `value` located at `slot`.\n */\n function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {\n /// @solidity memory-safe-assembly\n assembly {\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 /// @solidity memory-safe-assembly\n assembly {\n r.slot := store.slot\n }\n }\n}\n"
},
"contracts/interfaces/ICertificateVerifier.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\ninterface ICertificateVerifier {\n struct Signature {\n bytes32 r;\n bytes32 s;\n uint8 v;\n }\n\n struct EMPCertificate {\n string identifier;\n string name;\n string marktfunktion;\n string lieferant;\n string bilanzkreis;\n address owner;\n }\n\n struct CPOCertificate {\n string identifier;\n string name;\n address owner;\n }\n\n struct OtherCertificate {\n string identifier;\n string name;\n address owner;\n }\n\n function verifyEMP(\n bytes memory certificateData,\n bytes memory signature\n ) external view returns (address, EMPCertificate memory, Signature memory);\n\n function verifyCPO(\n bytes memory certificateData,\n bytes memory signature\n ) external view returns (address, CPOCertificate memory, Signature memory);\n\n function verifyOther(\n bytes memory certificateData,\n bytes memory signature\n ) external view returns (address, OtherCertificate memory, Signature memory);\n}\n"
},
"contracts/interfaces/IProviderOracle.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.24;\n\ninterface IProviderOracle {\n struct Provider {\n string name;\n string identifier;\n }\n\n function getProvider(\n string memory identifier\n ) external view returns (Provider memory);\n\n function addProvider(Provider memory provider) external;\n}\n"
},
"contracts/IOcnCvManager.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.24;\n\ninterface IOcnCvManager {\n /* ********************************** */\n /* ENUMS */\n /* ********************************** */\n\n enum CvStatus { NOT_VERIFIED, APPROVED, FAILED }\n\n}\n"
},
"contracts/IOcnPaymentManager.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.24;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface IOcnPaymentManager {\n /* ********************************** */\n /* ENUMS */\n /* ********************************** */\n\n enum PaymentStatus { PENDING, PAYMENT_UP_TO_DATE, INSUFFICIENT_FUNDS, INACTIVE }\n\n /* ********************************** */\n /* EVENTS */\n /* ********************************** */\n\n event OwnershipTransferred(address indexed oldAdmin, address indexed newAdmin);\n event PartyStaked(address stakedBy, address party, uint256 amount);\n event StakeWithdrawn(address indexed party, uint256 amount);\n\n /* ********************************** */\n /* FUNCTIONS */\n /* ********************************** */\n\n function initialize(address _euroStablecoin, uint256 _fundingYearlyAmount, address _operator) external;\n function pay(address party) external;\n function withdrawToRegistryOperator(address party) external;\n function getPaymentStatus(address party) external view returns (PaymentStatus);\n\n /* ********************************** */\n /* STORAGE VARIABLES */\n /* ********************************** */\n\n function euroStablecoin() external view returns (IERC20);\n function stakedFunds(address party) external view returns (uint256);\n function stakingBlock(address party) external view returns (uint256);\n\n /* ********************************** */\n /* ERRORS */\n /* ********************************** */\n\n error StakeAlreadyDeposited();\n error InsufficientAllowance();\n error TransferFailed();\n error NoFundsStaked();\n error WithdrawalNotAllowed();\n}\n"
},
"contracts/OcnPaymentManager.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.24;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IOcnPaymentManager} from \"./IOcnPaymentManager.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol\";\n\ncontract OcnPaymentManager is IOcnPaymentManager, AccessControlUpgradeable, UUPSUpgradeable {\n\n /* ********************************** */\n /* STORAGE VARIABLES */\n /* ********************************** */\n\n bytes32 public UPGRADER_ROLE;\n uint public version;\n address currentBaseContract;\n\n uint256 public fundingYearlyAmount; // Assuming the stablecoin has 18 decimals\n IERC20 public euroStablecoin; // ERC20 token contract address\n address public operatorAddress; // Address to receive the deposited yearly stakes\n uint256 public stakingPeriodInBlocks; // Amount of blocks to wait before withdrawing the stakes\n\n mapping(address => uint256) public stakingBlock; // Block when stake started by part\n mapping(address => uint256) public stakedFunds; // Amount staked by party\n\n uint256[50] __gap;\n\n /* ********************************** */\n /* INITIALIZER */\n /* ********************************** */\n\n function initialize(address _euroStablecoin, uint256 _fundingYearlyAmount, address _operator) public initializer {\n UPGRADER_ROLE = keccak256(\"UPGRADER_ROLE\");\n euroStablecoin = IERC20(_euroStablecoin);\n operatorAddress = _operator;\n fundingYearlyAmount = _fundingYearlyAmount * 1e18;\n stakingPeriodInBlocks = 2102400;\n\n __AccessControl_init();\n __UUPSUpgradeable_init();\n\n _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);\n _grantRole(UPGRADER_ROLE, msg.sender);\n }\n\n /**\n * Called when Base Contract upgrades: iterate version\n */\n function _authorizeUpgrade(address newImplementation)\n internal\n onlyRole(UPGRADER_ROLE)\n override\n {\n currentBaseContract = newImplementation;\n version++;\n }\n\n /* ********************************** */\n /* FUNCTIONS */\n /* ********************************** */\n\n /**\n * @notice Allows an operator to make a payment.\n */\n function pay(address party) external {\n uint256 currentStake = stakedFunds[party];\n if (currentStake > 0) {\n revert StakeAlreadyDeposited();\n }\n\n uint256 amount = euroStablecoin.allowance(msg.sender, address(this));\n if (amount < fundingYearlyAmount) {\n revert InsufficientAllowance();\n }\n\n if (!euroStablecoin.transferFrom(msg.sender, address(this), fundingYearlyAmount)) {\n revert TransferFailed();\n }\n\n stakedFunds[party] += fundingYearlyAmount;\n stakingBlock[party] = block.number;\n\n emit PartyStaked(msg.sender, party, fundingYearlyAmount);\n }\n\n /**\n * @notice Implements the withdrawal function\n * @param party The address whose stake should be withdrawn\n */\n function withdrawToRegistryOperator(address party) external {\n if (operatorAddress == address(0)) {\n revert(\"Withdrawal account not set\");\n }\n\n if (stakedFunds[party] == 0) {\n revert NoFundsStaked();\n }\n\n if (block.number < stakingBlock[party] + stakingPeriodInBlocks) {\n revert WithdrawalNotAllowed();\n }\n\n uint256 amountToWithdraw = stakedFunds[party];\n stakedFunds[party] = 0;\n\n if (!euroStablecoin.transfer(operatorAddress, amountToWithdraw)) {\n revert TransferFailed();\n }\n\n emit StakeWithdrawn(party, amountToWithdraw);\n }\n\n /**\n * @notice Sets the operator address to withdraw to\n **/\n function setOperator(address _operatorAddress) onlyRole(DEFAULT_ADMIN_ROLE) external {\n operatorAddress = _operatorAddress;\n }\n\n /**\n * @notice Returns the payment status of a given operator.\n * PAYMENT_UP_TO_DATE: has staked funds\n * INSUFFICIENT_FUNDS: has no staked funds but has made a payment before\n * PENDING: has not made any payment yet\n */\n function getPaymentStatus(address party) external view returns (PaymentStatus) {\n if (stakedFunds[party] > 0) {\n return PaymentStatus.PAYMENT_UP_TO_DATE;\n } else if (stakingBlock[party] > 0) {\n return PaymentStatus.INSUFFICIENT_FUNDS;\n } else {\n return PaymentStatus.PENDING;\n }\n }\n\n /**\n * @notice Sets the yearly required stake amount for the parties\n **/\n function setFundingYearlyAmount(uint256 _fundingYearlyAmount) onlyRole(DEFAULT_ADMIN_ROLE) external {\n fundingYearlyAmount = _fundingYearlyAmount * 1e18;\n }\n\n /**\n * @notice Gets the current required stake amount for the parties\n **/\n function getFundingYearlyAmount() external view returns (uint256) {\n return fundingYearlyAmount / 1e18;\n }\n\n /**\n * @notice Updates the ERC20 used for staking\n **/\n function setStablecoinAddress(address _euroStablecoin) onlyRole(DEFAULT_ADMIN_ROLE) external {\n euroStablecoin = IERC20(_euroStablecoin);\n }\n\n // To be used on deploy to transfer ownership from the deployer address to the Timelock Contract address\n function transferOwnership(address newOwner) public onlyRole(DEFAULT_ADMIN_ROLE) {\n // Grant DEFAULT_ADMIN_ROLE to new owner\n grantRole(DEFAULT_ADMIN_ROLE, newOwner);\n // Revoke DEFAULT_ADMIN_ROLE from current owner\n revokeRole(DEFAULT_ADMIN_ROLE, msg.sender);\n\n emit OwnershipTransferred(msg.sender, newOwner);\n }\n}\n"
},
"contracts/OcnRegistry.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity 0.8.24;\n\nimport {IOcnPaymentManager} from \"./IOcnPaymentManager.sol\";\nimport {IOcnCvManager} from \"./IOcnCvManager.sol\";\nimport \"./interfaces/ICertificateVerifier.sol\";\nimport \"./interfaces/IProviderOracle.sol\";\n\nimport {AccessControl} from \"@openzeppelin/contracts/access/AccessControl.sol\";\n\ncontract OcnRegistry is AccessControl {\n /* ********************************** */\n /* STORAGE VARIABLES */\n /* ********************************** */\n\n string private prefix;\n\n // OCN Node Operator Listings\n mapping(address => string) private nodeOf;\n mapping(string => bool) private uniqueDomains;\n mapping(address => bool) private uniqueOperators;\n address[] private operators;\n\n // OCPI Party Listings\n enum Role {\n CPO,\n EMSP,\n NAP,\n NSP,\n OTHER,\n SCSP\n }\n\n struct RoleDetails {\n bytes certificateData;\n bytes signature;\n Role role;\n }\n\n struct PartyDetails {\n bytes2 countryCode;\n bytes3 partyId;\n Role[] roles;\n string name;\n string url;\n IOcnPaymentManager.PaymentStatus paymentStatus;\n IOcnCvManager.CvStatus cvStatus;\n bool active;\n uint256 partyIndex;\n }\n\n mapping(bytes2 => mapping(bytes3 => address)) private uniqueParties;\n mapping(address => bool) private uniquePartyAddresses;\n mapping(address => PartyDetails) private partyOf;\n mapping(address => address) private operatorOf;\n mapping(address => bool) private allowedCertificateVerifiers;\n address[] private parties;\n\n IOcnPaymentManager public paymentManager;\n ICertificateVerifier public certificateVerifier;\n\n // Providers Oracle\n mapping(Role => IProviderOracle) private roleOracle;\n\n /* ********************************** */\n /* CUSTOM ERRORS */\n /* ********************************** */\n error EmptyDomainName(string reason);\n error DomainNameAlreadyRegistered(string reason);\n error EmptyCountryCode(string reason);\n error EmptyPartyId(string reason);\n error NoRolesProvided(string reason);\n error EmptyOperator(string reason);\n error PartyAlreadyRegistered(string reason);\n error PartyNotRegistered(string reason);\n error SignerMismatch(string reason);\n error InvalidCertificate(address verifier, string reason);\n error ProviderNotFound(Role role, string reason);\n error CerificateOwnerMismatch(string reason);\n\n /* ********************************** */\n /* EVENTS */\n /* ********************************** */\n\n event OwnershipTransferred(address indexed oldAdmin, address indexed newAdmin);\n event OperatorUpdate(address indexed operator, string domain);\n event PartyUpdate(bytes2 countryCode, bytes3 partyId, address indexed partyAddress, Role[] roles, string name, string url, IOcnPaymentManager.PaymentStatus paymentStatus, IOcnCvManager.CvStatus cvStatus, bool active, address indexed operatorAddress);\n\n event PartyDelete(bytes2 countryCode, bytes3 partyId, address indexed partyAddress, Role[] roles, string name, string url, IOcnPaymentManager.PaymentStatus paymentStatus, IOcnCvManager.CvStatus cvStatus, bool active);\n\n /* ********************************** */\n /* INITIALIZER */\n /* ********************************** */\n\n constructor(address _paymentManager, address _certificateVerifier) {\n prefix = \"\\u0019Ethereum Signed Message:\\n32\";\n paymentManager = IOcnPaymentManager(_paymentManager);\n certificateVerifier = ICertificateVerifier(_certificateVerifier);\n _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n function transferOwnership(address newOwner) public onlyRole(DEFAULT_ADMIN_ROLE) {\n grantRole(DEFAULT_ADMIN_ROLE, newOwner);\n revokeRole(DEFAULT_ADMIN_ROLE, msg.sender);\n\n emit OwnershipTransferred(msg.sender, newOwner);\n }\n\n function adminDeleteOperator(address operator) public onlyRole(DEFAULT_ADMIN_ROLE) {\n deleteNode(operator);\n }\n\n function adminDeleteParty(bytes2 countryCode, bytes3 partyId) public onlyRole(DEFAULT_ADMIN_ROLE) {\n address party = uniqueParties[countryCode][partyId];\n deleteParty(party);\n }\n\n function setNode(address operator, string memory domain) private {\n if (bytes(domain).length == 0) {\n revert EmptyDomainName(\"Cannot set empty domain name. Use deleteNode method instead.\");\n }\n if (uniqueDomains[domain]) {\n revert DomainNameAlreadyRegistered(\"Domain name already registered.\");\n }\n uniqueDomains[domain] = true;\n\n if (!uniqueOperators[operator]) {\n operators.push(operator);\n }\n\n uniqueOperators[operator] = true;\n nodeOf[operator] = domain;\n emit OperatorUpdate(operator, domain);\n }\n\n function setNode(string memory domain) public {\n setNode(msg.sender, domain);\n }\n\n function setNodeRaw(address operator, string memory domain, uint8 v, bytes32 r, bytes32 s) public {\n bytes32 paramHash = keccak256(abi.encodePacked(operator, domain));\n address signer = ecrecover(keccak256(abi.encodePacked(prefix, paramHash)), v, r, s);\n setNode(signer, domain);\n }\n\n function deleteNode(address operator) private {\n string memory domain = nodeOf[operator];\n if (bytes(domain).length == 0) {\n revert EmptyDomainName(\"Cannot delete node that does not exist.\");\n }\n uniqueDomains[domain] = false;\n delete nodeOf[operator];\n emit OperatorUpdate(operator, \"\");\n }\n\n function deleteNode() public {\n deleteNode(msg.sender);\n }\n\n function deleteNodeRaw(address operator, uint8 v, bytes32 r, bytes32 s) public {\n bytes32 paramHash = keccak256(abi.encodePacked(operator));\n address signer = ecrecover(keccak256(abi.encodePacked(prefix, paramHash)), v, r, s);\n deleteNode(signer);\n }\n\n function getNode(address operator) public view returns (string memory) {\n return nodeOf[operator];\n }\n\n function getNodeOperators() public view returns (address[] memory) {\n return operators;\n }\n\n function setParty(bytes2 countryCode, bytes3 partyId, RoleDetails[] memory roles, address operator, string memory name, string memory url) public {\n if (countryCode == bytes2(0)) {\n revert EmptyCountryCode(\"Cannot set empty country_code. Use deleteParty method instead.\");\n }\n if (partyId == bytes3(0)) {\n revert EmptyPartyId(\"Cannot set empty party_id. Use deleteParty method instead.\");\n }\n if (roles.length == 0) {\n revert NoRolesProvided(\"No roles provided.\");\n }\n if (operator == address(0)) {\n revert EmptyOperator(\"Cannot set empty operator. Use deleteParty method instead.\");\n }\n\n Role[] memory verifiedRoles = new Role[](roles.length);\n address credentialOwner = address(0);\n\n // VC verification (All roles must be verified)\n for (uint8 i = 0; i < roles.length; i++) {\n RoleDetails memory roleDetails = roles[i];\n (string memory certificateIdentifier, address owner) = verifyCertificate(roleDetails);\n\n if (credentialOwner == address(0)) {\n credentialOwner = owner;\n }\n\n if (credentialOwner != owner) {\n revert CerificateOwnerMismatch(\"Certificates have different owners\");\n }\n\n IProviderOracle oracle = roleOracle[roleDetails.role];\n if (address(oracle) != address(0)) {\n IProviderOracle.Provider memory provider = oracle.getProvider(certificateIdentifier);\n if (!compareIdentifiers(certificateIdentifier, provider.identifier)) {\n revert ProviderNotFound(roleDetails.role, \"Not active in oracle\");\n }\n }\n\n verifiedRoles[i] = roleDetails.role;\n }\n\n address registeredParty = uniqueParties[countryCode][partyId];\n if (registeredParty != address(0) && registeredParty != credentialOwner) {\n revert PartyAlreadyRegistered(\"Party with country_code/party_id already registered under different address.\");\n }\n uniqueParties[countryCode][partyId] = credentialOwner;\n if (bytes(nodeOf[operator]).length == 0) {\n revert PartyNotRegistered(\"Provided operator not registered.\");\n }\n\n uint256 partyIndex = partyOf[credentialOwner].partyIndex;\n if (!uniquePartyAddresses[credentialOwner]) {\n parties.push(credentialOwner);\n // get last index of the array\n partyIndex = parties.length - 1;\n }\n\n uniquePartyAddresses[credentialOwner] = true;\n\n IOcnPaymentManager.PaymentStatus paymentStatus = paymentManager.getPaymentStatus(credentialOwner);\n partyOf[credentialOwner] = PartyDetails(countryCode, partyId, verifiedRoles, name, url, paymentStatus, IOcnCvManager.CvStatus.NOT_VERIFIED, true, partyIndex);\n operatorOf[credentialOwner] = operator;\n\n PartyDetails memory details = partyOf[credentialOwner];\n emit PartyUpdate(details.countryCode, details.partyId, credentialOwner, details.roles, details.name, details.url, details.paymentStatus, details.cvStatus, details.active, operator);\n }\n\n function setPartyRaw(address party, bytes2 countryCode, bytes3 partyId, RoleDetails[] memory roles, address operator, string memory name, string memory url, uint8 v, bytes32 r, bytes32 s) public {\n bytes memory rolesBytes = \"\";\n for (uint8 i = 0; i < roles.length; i++) {\n RoleDetails memory roleDetails = roles[i];\n rolesBytes = abi.encodePacked(rolesBytes, roleDetails.certificateData, roleDetails.signature, roleDetails.role);\n }\n bytes32 rolesHash = keccak256(rolesBytes);\n bytes32 paramHash = keccak256(abi.encodePacked(party, countryCode, partyId, rolesHash, operator, name, url));\n address signer = ecrecover(keccak256(abi.encodePacked(prefix, paramHash)), v, r, s);\n if (signer != party) {\n revert SignerMismatch(\"Signer and provided party address different.\");\n }\n setParty(countryCode, partyId, roles, operator, name, url);\n }\n\n function deleteParty(address party) private {\n if (operatorOf[party] == address(0)) {\n revert PartyNotRegistered(\"Cannot delete party that does not exist. No operator found for given party.\");\n }\n delete operatorOf[party];\n PartyDetails memory details = partyOf[party];\n delete uniqueParties[details.countryCode][details.partyId];\n delete partyOf[party];\n delete parties[details.partyIndex];\n uniquePartyAddresses[party] = false;\n\n emit PartyDelete(details.countryCode, details.partyId, party, details.roles, details.name, details.url, details.paymentStatus, details.cvStatus, details.active);\n }\n\n function deleteParty() public {\n deleteParty(msg.sender);\n }\n\n function deletePartyRaw(address party, uint8 v, bytes32 r, bytes32 s) public {\n bytes32 paramHash = keccak256(abi.encodePacked(party));\n address signer = ecrecover(keccak256(abi.encodePacked(prefix, paramHash)), v, r, s);\n if (signer != party) {\n revert SignerMismatch(\"Signer and provided party address different.\");\n }\n deleteParty(signer);\n }\n\n function getOperatorByAddress(address party) public view returns (address operator, string memory domain) {\n operator = operatorOf[party];\n domain = nodeOf[operator];\n }\n\n function getOperatorByOcpi(bytes2 countryCode, bytes3 partyId) public view returns (address operator, string memory domain) {\n address party = uniqueParties[countryCode][partyId];\n operator = operatorOf[party];\n domain = nodeOf[operator];\n }\n\n function getPartyDetailsByAddress(address _partyAddress) public view returns (address partyAddress, bytes2 countryCode, bytes3 partyId, Role[] memory roles, IOcnPaymentManager.PaymentStatus paymentStatus, address operatorAddress, string memory name, string memory url, bool active) {\n PartyDetails storage details = partyOf[_partyAddress];\n partyAddress = _partyAddress;\n countryCode = details.countryCode;\n partyId = details.partyId;\n roles = details.roles;\n paymentStatus = details.paymentStatus;\n operatorAddress = operatorOf[_partyAddress];\n name = details.name;\n url = details.url;\n active = details.active;\n }\n\n function getPartyDetailsByOcpi(bytes2 _countryCode, bytes3 _partyId) public view returns (address partyAddress, bytes2 countryCode, bytes3 partyId, Role[] memory roles, IOcnPaymentManager.PaymentStatus paymentStatus, address operatorAddress, string memory name, string memory url, bool active) {\n partyAddress = uniqueParties[_countryCode][_partyId];\n PartyDetails storage details = partyOf[partyAddress];\n countryCode = details.countryCode;\n partyId = details.partyId;\n roles = details.roles;\n paymentStatus = details.paymentStatus;\n operatorAddress = operatorOf[partyAddress];\n name = details.name;\n url = details.url;\n active = details.active;\n }\n\n function getPartiesCount() public view returns (uint256) {\n return parties.length;\n }\n\n function getParties() public view returns (address[] memory) {\n return parties;\n }\n\n function getPartiesByOperator(address operator) public view returns (address[] memory) {\n address[] memory filteredParties = new address[](parties.length);\n uint32 count = 0;\n for (uint32 i = 0; i < parties.length; i++) {\n if (operatorOf[parties[i]] == operator) {\n filteredParties[count] = parties[i];\n count++;\n }\n }\n address[] memory result = new address[](count);\n for (uint32 i = 0; i < count; i++) {\n result[i] = filteredParties[i];\n }\n return result;\n }\n\n function getPartiesByRole(Role role) public view returns (address[] memory) {\n address[] memory filteredParties = new address[](parties.length);\n uint32 count = 0;\n for (uint32 i = 0; i < parties.length; i++) {\n PartyDetails memory details = partyOf[parties[i]];\n for (uint32 j = 0; j < details.roles.length; j++) {\n if (details.roles[j] == role) {\n filteredParties[count] = parties[i];\n count++;\n break;\n }\n }\n }\n address[] memory result = new address[](count);\n for (uint32 i = 0; i < count; i++) {\n result[i] = filteredParties[i];\n }\n return result;\n }\n\n function setVerifier(address verifier) public onlyRole(DEFAULT_ADMIN_ROLE) {\n require(verifier != address(0), \"Invalid verifier address\");\n require(!allowedCertificateVerifiers[verifier], \"Verifier already allowed\");\n\n allowedCertificateVerifiers[verifier] = true;\n }\n\n function removeVerifier(address verifier) public onlyRole(DEFAULT_ADMIN_ROLE) {\n require(verifier != address(0), \"Invalid verifier address\");\n require(allowedCertificateVerifiers[verifier], \"Verifier not currently allowed\");\n\n allowedCertificateVerifiers[verifier] = false;\n }\n\n function isAllowedVerifier(address verifier) public view returns (bool) {\n return allowedCertificateVerifiers[verifier];\n }\n\n function setProviderOracle(Role role, address oracleAddress) public onlyRole(DEFAULT_ADMIN_ROLE) {\n roleOracle[role] = IProviderOracle(oracleAddress);\n }\n\n function verifyCertificate(RoleDetails memory roleDetails) private view returns (string memory, address) {\n if (roleDetails.role == Role.EMSP) {\n (address verifier, ICertificateVerifier.EMPCertificate memory certificate, ) = certificateVerifier.verifyEMP(roleDetails.certificateData, roleDetails.signature);\n if (!isAllowedVerifier(verifier)) {\n revert InvalidCertificate(verifier, \"Invalid EMP certificate\");\n }\n return (certificate.identifier, certificate.owner);\n } else if (roleDetails.role == Role.CPO) {\n (address verifier, ICertificateVerifier.CPOCertificate memory certificate, ) = certificateVerifier.verifyCPO(roleDetails.certificateData, roleDetails.signature);\n if (!isAllowedVerifier(verifier)) {\n revert InvalidCertificate(verifier, \"Invalid CPO certificate\");\n }\n return (certificate.identifier, certificate.owner);\n } else {\n (address verifier, ICertificateVerifier.OtherCertificate memory certificate, ) = certificateVerifier.verifyOther(roleDetails.certificateData, roleDetails.signature);\n if (!isAllowedVerifier(verifier)) {\n revert InvalidCertificate(verifier, \"Invalid Other certificate\");\n }\n return (certificate.identifier, certificate.owner);\n }\n }\n\n function compareIdentifiers(string memory a, string memory b) private pure returns (bool) {\n return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));\n }\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"storageLayout",
"devdoc",
"userdoc",
"evm.gasEstimates"
],
"": [
"ast"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}