creation_sourcecode: {{
    "sources": {
      "lib/openzeppelin-contracts/contracts/access/IAccessControl.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\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     * _Available since v3.1._\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 `account`.\n     */\n    function renounceRole(bytes32 role, address account) external;\n}\n"
      },
      "lib/unlockdv2-wallet/src/interfaces/IACLManager.sol": {
        "content": "// SPDX-License-Identifier: AGPL-3.0\npragma solidity ^0.8.19;\n\nimport { IAccessControl } from \"@openzeppelin/contracts/access/IAccessControl.sol\";\n\n/**\n * @title IACLManager\n * @author Unlockd\n * @notice Defines the basic interface for the ACL Manager\n */\ninterface IACLManager is IAccessControl {\n    function UNLOCK_PROTOCOL() external view returns (address);\n\n    /**\n     * @notice Returns the identifier of the UtokenAdmin role\n     * @return The id of the UtokenAdmin role\n     */\n    function UTOKEN_ADMIN() external view returns (bytes32);\n\n    /**\n     * @notice Returns the identifier of the Protocol Admin role\n     * @return The id of the Protocol Admin role\n     */\n    function PROTOCOL_ADMIN() external view returns (bytes32);\n\n    /**\n     * @notice Returns the identifier of the PriceUpdater role\n     * @return The id of the PriceUpdater role\n     */\n    function PRICE_UPDATER() external view returns (bytes32);\n\n    /**\n     * @notice Returns the identifier of the EmergencyAdmin role\n     * @return The id of the EmergencyAdmin role\n     */\n    function AUCTION_ADMIN() external view returns (bytes32);\n\n    /**\n     * @notice Returns the identifier of the EmergencyAdmin role\n     * @return The id of the EmergencyAdmin role\n     */\n    function EMERGENCY_ADMIN() external view returns (bytes32);\n\n    /**\n     * @notice Returns the identifier of the Governance Admin role\n     * @return The id of the PriceUpdater role\n     */\n    function GOVERNANCE_ADMIN() external view returns (bytes32);\n\n    /**\n     * @notice Set the address of the protocol\n     * @dev Is the main address of the protocol.Only can be updated by the ADMIN.\n     * @param protocol address of the protocol\n     */\n    function setProtocol(address protocol) external;\n\n    /**\n     * @notice Returns true if the address is the protocol, false otherwise\n     * @param protocol The address to check\n     * @return True if the given address is the protocol, false otherwise\n     */\n    function isProtocol(address protocol) external view returns (bool);\n\n    /**\n     * @notice Set the role as admin of a specific role.\n     * @dev By default the admin role for all roles is `DEFAULT_ADMIN_ROLE`.\n     * @param role The role to be managed by the admin role\n     * @param adminRole The admin role\n     */\n    function setRoleAdmin(bytes32 role, bytes32 adminRole) external;\n\n    // UTOKEN\n    /**\n     * @notice Adds a new admin as  Utoken Admin\n     * @param admin The address of the new admin\n     */\n    function addUTokenAdmin(address admin) external;\n\n    /**\n     * @notice Removes an admin as  Utoken Admin\n     * @param admin The address of the admin to remove\n     */\n    function removeUTokenAdmin(address admin) external;\n\n    /**\n     * @notice Returns true if the address is Utoken Admin, false otherwise\n     * @param admin The address to check\n     * @return True if the given address is  Utoken Admin, false otherwise\n     */\n    function isUTokenAdmin(address admin) external view returns (bool);\n\n    // PROTOCOL\n    /**\n     * @notice Adds a new admin as  Protocol Admin\n     * @param admin The address of the new admin\n     */\n    function addProtocolAdmin(address admin) external;\n\n    /**\n     * @notice Removes an admin as  Protocol Admin\n     * @param admin The address of the admin to remove\n     */\n    function removeProtocolAdmin(address admin) external;\n\n    /**\n     * @notice Returns true if the address is Protocol Admin, false otherwise\n     * @param admin The address to check\n     * @return True if the given address is  Protocol Admin, false otherwise\n     */\n    function isProtocolAdmin(address admin) external view returns (bool);\n\n    // EMERGENCY\n    /**\n     * @notice Adds a new admin as EmergencyAdmin\n     * @param admin The address of the new admin\n     */\n    function addEmergencyAdmin(address admin) external;\n\n    /**\n     * @notice Removes an admin as EmergencyAdmin\n     * @param admin The address of the admin to remove\n     */\n    function removeEmergencyAdmin(address admin) external;\n\n    /**\n     * @notice Returns true if the address is EmergencyAdmin, false otherwise\n     * @param admin The address to check\n     * @return True if the given address is EmergencyAdmin, false otherwise\n     */\n    function isEmergencyAdmin(address admin) external view returns (bool);\n\n    // PRICE UPDATER\n    /**\n     * @notice Adds a new admin as PriceUpdater\n     * @param admin The address of the new PriceUpdater\n     */\n    function addPriceUpdater(address admin) external;\n\n    /**\n     * @notice Removes an admin as PriceUpdater\n     * @param admin The address of the PriceUpdater to remove\n     */\n    function removePriceUpdater(address admin) external;\n\n    /**\n     * @notice Returns true if the address is PriceUpdater, false otherwise\n     * @param admin The address to check\n     * @return True if the given address is PriceUpdater, false otherwise\n     */\n    function isPriceUpdater(address admin) external view returns (bool);\n\n    // Governance admin\n    /**\n     * @notice Adds a new admin as Govnernance admin\n     * @param admin The address of the new Governance admin\n     */\n    function addGovernanceAdmin(address admin) external;\n\n    /**\n     * @notice Removes an admin as Governance Admin\n     * @param admin The address of the Governance Admin to remove\n     */\n    function removeGovernanceAdmin(address admin) external;\n\n    /**\n     * @notice Returns true if the address is Governance Admin, false otherwise\n     * @param admin The address to check\n     * @return True if the given address is Governance Admin, false otherwise\n     */\n    function isGovernanceAdmin(address admin) external view returns (bool);\n}\n"
      },
      "lib/unlockdv2-wallet/src/interfaces/IAllowedControllers.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity 0.8.19;\n\ninterface IAllowedControllers {\n    event Collections(address indexed collections, bool isAllowed);\n\n    event DelegationController(address indexed delegationController, bool isAllowed);\n\n    function isAllowedDelegationController(address _controller) external view returns (bool);\n\n    function isAllowedCollection(address _collection) external view returns (bool);\n}\n"
      },
      "lib/unlockdv2-wallet/src/libs/allowed/AllowedControllers.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity 0.8.19;\n\nimport { IAllowedControllers } from \"../../interfaces/IAllowedControllers.sol\";\nimport { IACLManager } from \"../../interfaces/IACLManager.sol\";\nimport { Errors } from \"../helpers/Errors.sol\";\n\n/**\n * @title AllowedController\n * @author BootNode\n * @dev Registry for allowed addresses to be used as lock or delegation controllers in a DelegationWallet.\n */\ncontract AllowedControllers is IAllowedControllers {\n    /**\n     * @notice A mapping from a collections address\n     */\n    mapping(address => bool) private allowedCollections;\n\n    /**\n     * @notice A mapping from a controllers address to whether that address is allowed to be used by a DelegationWallet\n     * as a delegation controller.\n     */\n    mapping(address => bool) private allowedDelegationControllers;\n\n    /**\n     * @notice AclManager instance\n     */\n    IACLManager public immutable aclManager;\n\n    ////////////////////////////////////////\n    //  Modifiers\n    ////////////////////////////////////////\n    modifier onlyAdmin() {\n        if (!aclManager.isProtocolAdmin(msg.sender)) revert Errors.Caller_notAdmin();\n        _;\n    }\n\n    modifier onlyProtocol() {\n        if (!aclManager.isProtocol(msg.sender)) revert Errors.Caller_notProtocol();\n        _;\n    }\n\n    modifier onlyGov() {\n        if (!aclManager.isGovernanceAdmin(msg.sender)) revert Errors.Caller_notGovernanceAdmin();\n        _;\n    }\n\n    /**\n     * @notice Initialize `allowedDelegationControllers` with a batch of allowed\n     * controllers.\n     *\n     * @param _aclManager Address of the ACL manager\n     * @param _delegationControllers - The batch of delegation controller addresses initially allowed.\n     */\n    constructor(address _aclManager, address[] memory _delegationControllers) {\n        aclManager = IACLManager(_aclManager);\n        uint256 length = _delegationControllers.length;\n        for (uint256 j; j < length; ) {\n            _setDelegationControllerAllowance(_delegationControllers[j], true);\n            unchecked {\n                j++;\n            }\n        }\n    }\n\n    ////////////////////////////////////////\n    //  External Function\n    ////////////////////////////////////////\n    /**\n     * @notice This function can be called by admins to change the allowance status of all the collections.\n     *\n     * @param _collection - The address of the collection.\n     * @param _allowed - The new status of the collection.\n     */\n    function setCollectionAllowance(address _collection, bool _allowed) external onlyGov {\n        _setCollectionAllowance(_collection, _allowed);\n    }\n\n    /**\n     * @notice This function can be called by admins to change the permitted status of a batch of multiple collections.\n     *\n     * @param _collections - The addresses of the collections.\n     * @param _allowances - The new addresses of the collections.\n     */\n    function setCollectionsAllowances(address[] calldata _collections, bool[] calldata _allowances) external onlyGov {\n        if (_collections.length != _allowances.length)\n            revert Errors.AllowedCollections__setCollectionsAllowances_arityMismatch();\n\n        uint256 length = _collections.length;\n        for (uint256 i; i < length; ) {\n            _setCollectionAllowance(_collections[i], _allowances[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @notice This function can be called by admins to change the allowance status of a lock controller. This includes\n     * both adding a controller to the allowed list and removing it.\n     *\n     * @param _controller - The address of the controller whose allowance list status changed.\n     * @param _allowed - The new status of whether the controller is allowed or not.\n     */\n    function setDelegationControllerAllowance(address _controller, bool _allowed) external onlyAdmin {\n        _setDelegationControllerAllowance(_controller, _allowed);\n    }\n\n    /**\n     * @notice This function can be called by admins to change the permitted status of a batch of delegation\n     * controllers. This both adding a controller to the allowed list and removing it.\n     *\n     * @param _controllers - The addresses of the controllers whose allowance list status changed.\n     * @param _allowances - The new statuses of whether the controller is allowed or not.\n     */\n    function setDelegationControllerAllowances(\n        address[] calldata _controllers,\n        bool[] calldata _allowances\n    ) external onlyAdmin {\n        if (_controllers.length != _allowances.length)\n            revert Errors.AllowedControllers__setDelegationControllerAllowances_arityMismatch();\n\n        uint256 length = _controllers.length;\n        for (uint256 i; i < length; ) {\n            _setDelegationControllerAllowance(_controllers[i], _allowances[i]);\n            unchecked {\n                ++i;\n            }\n        }\n    }\n\n    /**\n     * @notice Checks if an collection address is an allowed .\n     *\n     * @param _collection - The address of the controller.\n     */\n    function isAllowedCollection(address _collection) external view returns (bool) {\n        if (_collection == address(0)) return false;\n        return allowedCollections[_collection];\n    }\n\n    /**\n     * @notice Checks if an address is an allowed delegation controller.\n     *\n     * @param _controller - The address of the controller.\n     */\n    function isAllowedDelegationController(address _controller) external view returns (bool) {\n        return allowedDelegationControllers[_controller];\n    }\n\n    /**\n     * @notice Changes the allowance status of an lock controller. This includes both adding a controller to the\n     * allowed list and removing it.\n     *\n     * @param _collection - The address of the controller whose allowance list status changed.\n     * @param _allowed - The new status of whether the controller is allowed or not.\n     */\n    function _setCollectionAllowance(address _collection, bool _allowed) internal {\n        if (_collection == address(0)) revert Errors.AllowedCollections__setCollectionsAllowances_invalidAddress();\n\n        allowedCollections[_collection] = _allowed;\n\n        emit Collections(_collection, _allowed);\n    }\n\n    /**\n     * @notice Changes the allowance status of an delegation controller. This includes both adding a controller to the\n     * allowed list and removing it.\n     *\n     * @param _delegationController - The address of the controller whose allowance list status changed.\n     * @param _allowed - The new status of whether the controller is allowed or not.\n     */\n    function _setDelegationControllerAllowance(address _delegationController, bool _allowed) internal {\n        if (_delegationController == address(0))\n            revert Errors.AllowedControllers__setDelegationControllerAllowance_invalidAddress();\n\n        allowedDelegationControllers[_delegationController] = _allowed;\n\n        emit DelegationController(_delegationController, _allowed);\n    }\n}\n"
      },
      "lib/unlockdv2-wallet/src/libs/helpers/Errors.sol": {
        "content": "// SPDX-License-Identifier: agpl-3.0\npragma solidity 0.8.19;\n\nlibrary Errors {\n    // ========== General ===========\n    error Caller_notProtocol();\n    error Caller_notGovernanceAdmin();\n    error Caller_notAdmin();\n    // ========== Delegation Recipes ===========\n    error DelegationRecipes__add_arityMismatch();\n    error DelegationRecipes__remove_arityMismatch();\n\n    // ========== Delegation Owner ===========\n\n    error DelegationGuard__initialize_invalidGuardBeacon();\n    error DelegationGuard__initialize_invalidRecipes();\n    error DelegationGuard__initialize_invalidSafe();\n    error DelegationGuard__initialize_invalidOwner();\n    error DelegationGuard__initialize_aclManager();\n    error DelegationOwner__assetNotLocked();\n    error DelegationOwner__wrongLoanId();\n    error DelegationOwner__assetAlreadyLocked();\n    error DelegationOwner__collectionNotAllowed();\n    error DelegationOwner__onlyOwner();\n    error DelegationOwner__onlyDelegationController();\n    error DelegationOwner__onlyLockController();\n    error DelegationOwner__onlyDelegationCreator();\n    error DelegationOwner__onlySignatureDelegationCreator();\n    error DelegationOwner__onlyLockCreator();\n\n    error DelegationOwner__delegate_currentlyDelegated();\n    error DelegationOwner__delegate_invalidDelegatee();\n    error DelegationOwner__delegate_invalidDuration();\n    error DelegationOwner__delegate_assetLocked();\n\n    error DelegationOwner__deposit_collectionNotAllowed();\n    error DelegationOwner__delegateSignature_invalidArity();\n    error DelegationOwner__delegateSignature_currentlyDelegated();\n    error DelegationOwner__delegateSignature_invalidDelegatee();\n    error DelegationOwner__delegateSignature_invalidDuration();\n    error DelegationOwner__endDelegateSignature_invalidArity();\n\n    error DelegationOwner__isValidSignature_notDelegated();\n    error DelegationOwner__isValidSignature_invalidSigner();\n    error DelegationOwner__isValidSignature_invalidExecSig();\n\n    error DelegationOwner__execTransaction_notDelegated();\n    error DelegationOwner__execTransaction_invalidDelegatee();\n    error DelegationOwner__execTransaction_notAllowedFunction();\n    error DelegationOwner__execTransaction_notSuccess();\n\n    error DelegationOwner__lockAsset_assetLocked();\n    error DelegationOwner__lockAsset_invalidClaimDate();\n\n    error DelegationOwner__changeClaimDate_invalidClaimDate();\n\n    error DelegationOwner__claimAsset_assetNotClaimable();\n    error DelegationOwner__claimAsset_assetLocked();\n    error DelegationOwner__claimAsset_notSuccess();\n\n    error DelegationOwner__changeOwner_notSuccess();\n    error DelegationOwner__transferAsset_assetNotOwned();\n    error DelegationOwner__approveAsset_assetNotOwned();\n\n    error DelegationOwner__checkOwnedAndNotApproved_assetNotOwned();\n    error DelegationOwner__checkOwnedAndNotApproved_assetApproved();\n\n    error DelegationOwner__checkClaimDate_assetDelegatedLonger();\n    error DelegationOwner__checkClaimDate_signatureDelegatedLonger();\n\n    error DelegationOwner__lockCreatorChecks_assetNotLocked();\n    error DelegationOwner__lockCreatorChecks_onlyLockCreator();\n\n    error DelegationOwner__delegationCreatorChecks_notDelegated();\n    error DelegationOwner__delegationCreatorChecks_onlyDelegationCreator();\n\n    error DelegationOwner__setDelegationController_notAllowedController();\n    error DelegationOwner__setLockController_notAllowedController();\n\n    error DelegationOwner__batchSetLoanId_arityMismatch();\n    // ========== Guard Owner ===========\n    error GuardOwner__initialize_aclManager();\n    error GuardOwner__initialize_invalidGuardBeacon();\n    error GuardOwner__initialize_invalidSafe();\n    error GuardOwner__initialize_invalidOwner();\n    error GuardOwner__initialize_invalidDelegationOwner();\n    error GuardOwner__initialize_invalidProtocolOwner();\n\n    // ========== Transaction Guard ===========\n    error TransactionGuard__onlyManagersOwner();\n    error TransactionGuard__initialize_invalidDelegationOwner();\n    error TransactionGuard__initialize_invalidProtocolOwner();\n    error TransactionGuard__checkTransaction_noDelegateCall();\n    error TransactionGuard__checkApproveForAll_noApprovalForAll();\n\n    error TransactionGuard__checkLocked_noTransfer();\n    error TransactionGuard__checkLocked_noApproval();\n    error TransactionGuard__checkLocked_noBurn();\n    error TransactionGuard__checkConfiguration_ownershipChangesNotAllowed();\n    error TransactionGuard__checkConfiguration_guardChangeNotAllowed();\n    error TransactionGuard__checkConfiguration_enableModuleNotAllowed();\n    error TransactionGuard__checkConfiguration_setFallbackHandlerNotAllowed();\n\n    // ========== Allowed Collection ===========\n    error AllowedCollections__setCollectionsAllowances_invalidAddress();\n    error AllowedCollections__setCollectionsAllowances_arityMismatch();\n\n    error AllowedControllers__setLockControllerAllowances_arityMismatch();\n    error AllowedControllers__setDelegationControllerAllowances_arityMismatch();\n    error AllowedControllers__setDelegationControllerAllowance_invalidAddress();\n\n    // ========== Delegation Wallet Registry ===========\n    error DelegationWalletRegistry__onlyFactoryOrOwner();\n\n    error DelegationWalletRegistry__setFactory_invalidAddress();\n\n    error DelegationWalletRegistry__setWallet_invalidWalletAddress();\n    error DelegationWalletRegistry__setWallet_invalidOwnerAddress();\n    error DelegationWalletRegistry__setWallet_invalidDelegationOwnerAddress();\n    error DelegationWalletRegistry__setWallet_invalidGuardAddress();\n    error DelegationWalletRegistry__setWallet_invalidProtocolOwnerAddress();\n\n    // ========== Protocol OWNER ===========\n    error ProtocolOwner__invalidDelegatedAddressAddress();\n    error ProtocolOwner__execTransaction_notSuccess();\n}\n"
      }
    },
    "settings": {
      "remappings": [
        "ds-test/=lib/forge-std/lib/ds-test/src/",
        "forge-std/=lib/forge-std/src/",
        "solady/=lib/solady/src/",
        "@openzeppelin/=lib/openzeppelin-contracts/",
        "@openzeppelin-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
        "@chainlink/=lib/chainlink/",
        "@unlockd-wallet/=lib/unlockdv2-wallet/",
        "@solady/=lib/solady/src/",
        "@maxapy/=lib/maxapy/src/",
        "@gnosis.pm/safe-contracts/=lib/unlockdv2-wallet/lib/safe-contracts/",
        "chainlink/=lib/chainlink/",
        "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
        "maxapy/=lib/maxapy/",
        "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
        "openzeppelin-contracts/=lib/openzeppelin-contracts/",
        "openzeppelin/=lib/openzeppelin-contracts/contracts/",
        "safe-contracts/=lib/unlockdv2-wallet/lib/safe-contracts/contracts/",
        "unlockdv2-wallet/=lib/unlockdv2-wallet/src/"
      ],
      "optimizer": {
        "enabled": true,
        "runs": 200
      },
      "metadata": {
        "useLiteralContent": false,
        "bytecodeHash": "ipfs",
        "appendCBOR": true
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      },
      "evmVersion": "paris",
      "libraries": {}
    },
    "language": "Solidity"
  }}