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/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\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 amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` 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 amount) 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 `amount` as the allowance of `spender` over the 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 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `from` to `to` using the\n     * allowance mechanism. `amount` 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 amount) external returns (bool);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n *\n * ==== Security Considerations\n *\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\n * generally recommended is:\n *\n * ```solidity\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\n *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\n *     doThing(..., value);\n * }\n *\n * function doThing(..., uint256 value) public {\n *     token.safeTransferFrom(msg.sender, address(this), value);\n *     ...\n * }\n * ```\n *\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\n * {SafeERC20-safeTransferFrom}).\n *\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\n * contracts should have entry points that don't rely on permit.\n */\ninterface IERC20Permit {\n    /**\n     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n     * given ``owner``'s signed approval.\n     *\n     * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n     * ordering also apply here.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `deadline` must be a timestamp in the future.\n     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n     * over the EIP712-formatted function arguments.\n     * - the signature must use ``owner``'s current nonce (see {nonces}).\n     *\n     * For more information on the signature format, see the\n     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n     * section].\n     *\n     * CAUTION: See Security Considerations above.\n     */\n    function permit(\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) external;\n\n    /**\n     * @dev Returns the current nonce for `owner`. This value must be\n     * included whenever a signature is generated for {permit}.\n     *\n     * Every successful call to {permit} increases ``owner``'s nonce by one. This\n     * prevents a signature from being used multiple times.\n     */\n    function nonces(address owner) external view returns (uint256);\n\n    /**\n     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n     */\n    // solhint-disable-next-line func-name-mixedcase\n    function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using Address for address;\n\n    /**\n     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    /**\n     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\n     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\n     */\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        require(\n            (value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    /**\n     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 oldAllowance = token.allowance(address(this), spender);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n    }\n\n    /**\n     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful.\n     */\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        unchecked {\n            uint256 oldAllowance = token.allowance(address(this), spender);\n            require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\n        }\n    }\n\n    /**\n     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\n     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\n     * to be set to zero before setting it to a non-zero value, such as USDT.\n     */\n    function forceApprove(IERC20 token, address spender, uint256 value) internal {\n        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);\n\n        if (!_callOptionalReturnBool(token, approvalCall)) {\n            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n            _callOptionalReturn(token, approvalCall);\n        }\n    }\n\n    /**\n     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n     * Revert on invalid signature.\n     */\n    function safePermit(\n        IERC20Permit token,\n        address owner,\n        address spender,\n        uint256 value,\n        uint256 deadline,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n    ) internal {\n        uint256 nonceBefore = token.nonces(owner);\n        token.permit(owner, spender, value, deadline, v, r, s);\n        uint256 nonceAfter = token.nonces(owner);\n        require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     *\n     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\n     */\n    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false\n        // and not revert is the subcall reverts.\n\n        (bool success, bytes memory returndata) = address(token).call(data);\n        return\n            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n    }\n}\n"
      },
      "lib/openzeppelin-contracts/contracts/utils/Address.sol": {
        "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     *\n     * Furthermore, `isContract` will also return true if the target contract within\n     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n     * which only has an effect at the end of a transaction.\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\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.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\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, it is bubbled up by this\n     * function (like regular Solidity function calls).\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     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\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     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a delegate call.\n     *\n     * _Available since v3.4._\n     */\n    function functionDelegateCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        (bool success, bytes memory returndata) = target.delegatecall(data);\n        return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n     *\n     * _Available since v4.8._\n     */\n    function verifyCallResultFromTarget(\n        address target,\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        if (success) {\n            if (returndata.length == 0) {\n                // only check isContract if the call was successful and the return data is empty\n                // otherwise we already know that it was a contract\n                require(isContract(target), \"Address: call to non-contract\");\n            }\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    /**\n     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason or using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            _revert(returndata, errorMessage);\n        }\n    }\n\n    function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage);\n        }\n    }\n}\n"
      },
      "lib/unlockdv2-wallet/src/interfaces/IProtocolOwner.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\ninterface IProtocolOwner {\n    ////////////////////////////////////////////////////////////////////////////////\n    // Events\n    ////////////////////////////////////////////////////////////////////////////////\n\n    event SetLockController(address indexed lockController, bool allowed);\n    event ChangeOwner(address indexed asset, uint256 indexed assetId, address newOwner);\n    event LockedAsset(\n        address indexed asset,\n        uint256 indexed assetId,\n        uint256 claimDate,\n        address indexed lockController\n    );\n\n    event UnlockedAsset(address indexed asset, uint256 indexed assetId, address indexed lockController);\n    event ClaimedAsset(address indexed asset, uint256 indexed assetId, address indexed receiver);\n    event TransferredAsset(address indexed asset, uint256 indexed assetId, address indexed receiver);\n\n    event SetLoanId(bytes32 index, bytes32 loanId);\n    event SetBatchLoanId(bytes32[] indexed assets, bytes32 indexed loanId);\n\n    ////////////////////////////////////////////////////////////////////////////////\n    // Functions\n    ////////////////////////////////////////////////////////////////////////////////\n\n    function approveSale(\n        address _collection,\n        uint256 _tokenId,\n        address _underlyingAsset,\n        uint256 _amount,\n        address _marketApproval,\n        bytes32 _loanId\n    ) external;\n\n    // Delegatee Functions\n    function execTransaction(\n        address _to,\n        uint256 _value,\n        bytes calldata _data,\n        uint256 _safeTxGas,\n        uint256 _baseGas,\n        uint256 _gasPrice,\n        address _gasToken,\n        address payable _refundReceiver\n    ) external returns (bool success);\n\n    function delegateOneExecution(address to, bool value) external;\n\n    function isDelegatedExecution(address to) external view returns (bool);\n\n    function isAssetLocked(bytes32 _id) external view returns (bool);\n\n    function batchSetLoanId(bytes32[] calldata _assets, bytes32 _loanId) external;\n\n    function batchSetToZeroLoanId(bytes32[] calldata _assets) external;\n\n    function changeOwner(address _asset, uint256 _id, address _newOwner) external;\n\n    function getLoanId(bytes32 _assetId) external view returns (bytes32);\n\n    function setLoanId(bytes32 _assetId, bytes32 _loanId) external;\n\n    function safeSetLoanId(address _asset, uint256 _id, bytes32 _loanId) external;\n}\n"
      },
      "src/interfaces/IACLManager.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\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  /**\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 Returns the identifier of the WRAPPER ADAPTER role\n   * @return The id of the PriceUpdater role\n   */\n  function WRAPPER_ADAPTER() 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  // AUCTION ADMIN\n  /**\n   * @notice Adds a new admin as  Auction Admin\n   * @param admin The address of the new admin\n   */\n  function addAuctionAdmin(address admin) external;\n\n  /**\n   * @notice Removes an admin as  Auction Admin\n   * @param admin The address of the admin to remove\n   */\n  function removeAuctionAdmin(address admin) external;\n\n  /**\n   * @notice Returns true if the address is Auction Admin, false otherwise\n   * @param admin The address to check\n   * @return True if the given address is  Auction Admin, false otherwise\n   */\n  function isAuctionAdmin(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  // Wrapper ADAPTER\n  /**\n   * @notice Adds a new adapter as WRAPPER_ADAPTER\n   * @param adapter The address of the new adapter\n   */\n  function addWrapperAdapter(address adapter) external;\n\n  /**\n   * @notice Removes an adapter as WRAPPER_ADAPTER\n   * @param adapter The address of the WRAPPER_ADAPTER to remove\n   */\n  function removeWrapperAdapter(address adapter) external;\n\n  /**\n   * @notice Returns true if the address is WRAPPER_ADAPTER, false otherwise\n   * @param adapter The address to check\n   * @return True if the given address is WRAPPER_ADAPTER, false otherwise\n   */\n  function isWrapperAdapter(address adapter) external view returns (bool);\n}\n"
      },
      "src/interfaces/IEmergency.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\ninterface IEmergency {\n  function emergencyWithdraw(address payable _to) external;\n\n  function emergencyWithdrawERC20(address _asset, address _to) external;\n}\n"
      },
      "src/interfaces/adapter/IMarketAdapter.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\nimport {DataTypes} from '../../types/DataTypes.sol';\n\ninterface IMarketAdapter {\n  ///////////////////////////////////////////////\n  // STRUCTS\n  ///////////////////////////////////////////////\n\n  struct PreSellParams {\n    bytes32 loanId;\n    address collection;\n    uint256 tokenId;\n    address underlyingAsset;\n    uint256 marketPrice;\n    address marketApproval;\n    address protocolOwner;\n  }\n\n  struct SellParams {\n    address collection;\n    uint256 tokenId;\n    address wallet;\n    address protocolOwner;\n    address underlyingAsset;\n    uint256 marketPrice;\n    address marketApproval;\n    address to;\n    uint256 value;\n    bytes data;\n  }\n\n  struct PreBuyParams {\n    bytes32 loanId;\n    address collection;\n    uint256 tokenId;\n    address underlyingAsset;\n    uint256 marketPrice;\n    address marketApproval;\n    address protocolOwner;\n  }\n\n  struct BuyParams {\n    address wallet;\n    address underlyingAsset;\n    uint256 marketPrice;\n    address marketApproval;\n    address to;\n    uint256 value;\n    bytes data;\n  }\n\n  function preBuy(PreBuyParams memory params) external payable;\n\n  function buy(BuyParams memory params) external payable returns (uint256);\n\n  function preSell(PreSellParams memory params) external payable;\n\n  function sell(SellParams memory params) external payable;\n}\n"
      },
      "src/libraries/base/BaseEmergency.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {IACLManager} from '../../interfaces/IACLManager.sol';\nimport {IEmergency} from '../../interfaces/IEmergency.sol';\nimport {Errors} from '../helpers/Errors.sol';\n\n/**\n * @title BaseEmergency\n * @notice Base logic to recover funds\n * @author Unlockd\n */\ncontract BaseEmergency is IEmergency {\n  using SafeERC20 for IERC20;\n\n  address immutable _aclManager;\n  /**\n   * @dev Modifier that checks if the sender has Protocol Emergency Admin ROLE\n   */\n  modifier onlyEmergencyAdmin() {\n    if (!IACLManager(_aclManager).isEmergencyAdmin(msg.sender)) {\n      revert Errors.ProtocolAccessDenied();\n    }\n    _;\n  }\n\n  constructor(address aclManager) {\n    if (aclManager == address(0)) revert Errors.ZeroAddress();\n    _aclManager = aclManager;\n  }\n\n  /**\n   * @dev Execute emegency native withdraw, only executable by the emergency admin\n   * @param _to address to send the amount\n   */\n  function emergencyWithdraw(address payable _to) external onlyEmergencyAdmin {\n    (bool sent, ) = _to.call{value: address(this).balance}('');\n    if (sent == false) revert Errors.UnsuccessfulExecution();\n  }\n\n  /**\n   * @dev Execute emegency ERC20 withdraw, only executable by the emergency admin\n   * @param _to address to send the amount\n   */\n  function emergencyWithdrawERC20(address _asset, address _to) external onlyEmergencyAdmin {\n    IERC20(_asset).safeTransfer(_to, IERC20(_asset).balanceOf(address(this)));\n  }\n}\n"
      },
      "src/libraries/helpers/Constants.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\nlibrary Constants {\n  ////////////////////////////////////////////\n  // Reentrancy Guard for modules\n  ////////////////////////////////////////////\n  uint256 internal constant REENTRANCYLOCK__UNLOCKED = 0; // prettier-ignore\n  uint256 internal constant REENTRANCYLOCK__LOCKED   = 2; // prettier-ignore\n\n  ////////////////////////////////////////////\n  // Modules Configuration\n  ////////////////////////////////////////////\n\n  uint256 internal constant MAX_EXTERNAL_SINGLE_PROXY_MODULEID = 499_999; // prettier-ignore\n  uint256 internal constant MAX_EXTERNAL_MODULEID              = 999_999; // prettier-ignore\n\n  ////////////////////////////////////////////\n  // List Modules\n  ////////////////////////////////////////////\n\n  // Public single-proxy modules\n  uint256 internal constant MODULEID__INSTALLER  = 1; // prettier-ignore\n  uint256 internal constant MODULEID__MANAGER    = 2; // prettier-ignore\n  uint256 internal constant MODULEID__ACTION     = 3; // prettier-ignore\n  uint256 internal constant MODULEID__AUCTION    = 4; // prettier-ignore\n  uint256 internal constant MODULEID__MARKET     = 5; // prettier-ignore\n  uint256 internal constant MODULEID__BUYNOW     = 6; // prettier-ignore\n  uint256 internal constant MODULEID__SELLNOW    = 7; // prettier-ignore\n\n  ////////////////////////////////////////////\n  // RESERVE STATE\n  ////////////////////////////////////////////\n\n  enum ReserveState {\n    STOPPED, // No supply, No borrow\n    FREEZED, // No supply, No withdraw , No borrow, No repay\n    ACTIVE // All OK\n  }\n\n  ////////////////////////////////////////////\n  // LOAN STATE\n  ////////////////////////////////////////////\n\n  enum LoanState {\n    BLOCKED,\n    ACTIVE,\n    FREEZE\n  }\n\n  ////////////////////////////////////////////\n  // GRUP RESERVE TYPE\n  ////////////////////////////////////////////\n\n  enum ReserveType {\n    DISABLED, // Disabled collection\n    ALL, // All the assets with the exception SPECIAL\n    STABLE, // For the stable coins\n    COMMON, // Common coins WETH etc ...\n    SPECIAL // Only if the collection is also isolated to one asset token\n  }\n\n  ////////////////////////////////////////////\n  // ORDER TYPE\n  ////////////////////////////////////////////\n\n  enum OrderType {\n    TYPE_LIQUIDATION_AUCTION,\n    //Auction with BIDs\n    TYPE_AUCTION,\n    // Fixed price only buynow function\n    TYPE_FIXED_PRICE,\n    // Fixed price and auction with bids\n    TYPE_FIXED_PRICE_AND_AUCTION\n  }\n}\n"
      },
      "src/libraries/helpers/Errors.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\n/**\n * @title Errors library\n * @author Unlockd\n * @notice Defines the error messages emitted by the different contracts of the Unlockd protocol\n */\nlibrary Errors {\n  ///////////////////////////////////////////\n  ///   GENERIC\n  ///////////////////////////////////////////\n\n  error AccessDenied();\n  //error ZeroAddress(string paramName);\n\n  error InvalidParam(string paramName);\n  error ArrayLengthMismatch(string details);\n  error InvalidArrayLength();\n  error Paused();\n  error Frozen();\n\n  error AddressesNotEquals();\n  error NumbersNotEquals();\n\n  error ZeroAddress();\n  error ZeroBytes();\n  error ZeroNumber();\n\n  error ACLAdminZeroAddress();\n\n  error UTokenNotAllowed();\n  error AdapterNotAllowed();\n  error TimestampExpired();\n  error TimestampNotExpired();\n  error NotImplemented();\n\n  error InvalidParams();\n  error InvalidModule();\n  error InvalidCurrentLtv();\n  error InvalidTotalAmount();\n  error InvalidCurrentLiquidationThreshold();\n  error InvalidUserCollateralBalance();\n  error InvalidOrderOwner();\n  error InvalidOrderBuyer();\n  error InvalidBidAmount();\n  error InvalidLoanOwner();\n  error InvalidUnderlyingAsset();\n  error InvalidAssets();\n  error InvalidEndAmount();\n  error InvalidStartAmount();\n  error InvalidEndTime();\n  error InvalidStartTime();\n\n  error InvalidPriceFeedKey();\n  error InvalidAggregator();\n  error InvalidLastRoundData();\n\n  error NotEnoughLiquidity();\n  error DebtExceedsAmount();\n  error AmountExceedsDebt();\n  error AmountExceedsBalance();\n  error AmountToLow();\n  error CollectionNotAllowed();\n  error NotAssetOwner();\n  error UnsuccessfulExecution();\n  error AssetsMismatch();\n  error InvalidRecoveredAddress();\n  error SenderZeroAddress();\n  error OrderActive();\n\n  error WrongNonce();\n\n  error NotEqualDeadline();\n  error NotEqualUnderlyingAsset();\n  error NotEqualTotalAssets();\n  error NotEqualOrderOwner();\n  error NotEqualSender();\n\n  error ProtocolAccessDenied();\n  error GovernanceAccessDenied();\n  error EmergencyAccessDenied();\n  error RoleAccessDenied();\n  error MarketPriceNotCoverDebt();\n  error StrategyNotEmpty();\n\n  error InvalidDepositCap();\n  error InvalidBorrowCap();\n  error PoolNotActive();\n  error PoolPaused();\n  error PoolFrozen();\n\n  ///////////////////////////////////////////\n  ///   RESERVE CONFIG\n  ///////////////////////////////////////////\n\n  error InvalidReserveFactor();\n  error InvalidMaxBorrowCap();\n  error InvalidMaxDepositCap();\n  error InvalidMaxMinCap();\n  error InvalidMaxDecimals();\n  ///////////////////////////////////////////\n  ///   UTOKEN\n  ///////////////////////////////////////////\n  error UnderlyingMarketNotExist();\n  error UnderlyingMarketAlreadyExist();\n  error UTokenAccessDenied();\n  error ReserveNotActive();\n  error NotValidReserve();\n  ///////////////////////////////////////////\n  ///   ROUTER\n  ///////////////////////////////////////////\n\n  error BaseInputToShort();\n  error ReentrancyLocked();\n  error RevertEmptyBytes();\n  ///////////////////////////////////////////\n  ///   WALLET\n  ///////////////////////////////////////////\n\n  error UnlockdWalletNotFound();\n  error InvalidWalletOwner();\n  error NotEqualWallet();\n  error ProtocolOwnerZeroAddress();\n\n  ///////////////////////////////////////////\n  ///   LOAN\n  ///////////////////////////////////////////\n\n  error HealtyLoan();\n  error UnhealtyLoan();\n  error UnableToBorrowMore();\n  error LoanNotActive();\n  error LowCollateral();\n  error InvalidLoanId();\n  error LoanNotUpdated();\n  error LoanBlocked();\n  error LoanWithDebtRepayed();\n  ///////////////////////////////////////////\n  ///   ORDER\n  ///////////////////////////////////////////\n\n  error OrderNotAllowed();\n  error InvalidOrderId();\n\n  ///////////////////////////////////////////\n  ///   ASSETS\n  ///////////////////////////////////////////\n\n  error InvalidAssetAmount();\n  error InvalidAmount();\n  error AssetLocked();\n  error AssetUnlocked();\n  error LiquidityRateOverflow();\n  error LiquidityIndexOverflow();\n  error BorrorRateOverflow();\n  error BorrowIndexOverflow();\n\n  ///////////////////////////////////////////\n  ///   WRAPPERS\n  ///////////////////////////////////////////\n\n  error TransferNotSupported();\n  error ApproveNotSupported();\n  error SetApprovalForAllNotSupported();\n  error StreamERC20NotSupported();\n  error CallerNotNFTOwner();\n  error StreamCancelable();\n  error StreamNotTransferable();\n  error BurnerNotApproved();\n  error ERC721ReceiverNotSupported();\n\n  error ERC1155AmountNotValid();\n  error ERC1155BatchNotAllowed();\n  error NotWrapperAdapter();\n  error SoldForASmallerAmount();\n\n  function verifyNotZero(address addr) internal pure {\n    if (addr == address(0)) {\n      revert ZeroAddress();\n    }\n  }\n\n  function verifyNotZero(bytes32 key) internal pure {\n    if (key == bytes32(0)) {\n      revert ZeroBytes();\n    }\n  }\n\n  function verifyNotZero(uint256 num) internal pure {\n    if (num == 0) {\n      revert ZeroNumber();\n    }\n  }\n\n  function verifyAreEquals(address ad1, address ad2) internal pure {\n    if (ad1 != ad2) {\n      revert AddressesNotEquals();\n    }\n  }\n\n  function verifyAreEquals(uint256 pa1, uint256 pa2) internal pure {\n    if (pa1 != pa2) {\n      revert NumbersNotEquals();\n    }\n  }\n\n  function verifyNotExpiredTimestamp(uint256 endTimestamp, uint256 nowTimestamp) internal pure {\n    assembly {\n      // if (endTimestamp <= nowTimestamp)\n      if iszero(gt(endTimestamp, nowTimestamp)) {\n        mstore(0x00, 0x26c69d1a) // TimestampExpired() selector\n        revert(0x1c, 0x04)\n      }\n    }\n  }\n\n  function verifyExpiredTimestamp(uint256 endTimestamp, uint256 nowTimestamp) internal pure {\n    assembly {\n      // if (endTimestamp > nowTimestamp)\n      if gt(endTimestamp, nowTimestamp) {\n        mstore(0x00, 0x2499486c) // TimestampNotExpired() selector\n        revert(0x1c, 0x04)\n      }\n    }\n  }\n}\n"
      },
      "src/protocol/adapters/ReservoirAdapter.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\nimport {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';\nimport {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';\nimport {Address} from '@openzeppelin/contracts/utils/Address.sol';\n\nimport {IProtocolOwner} from '@unlockd-wallet/src/interfaces/IProtocolOwner.sol';\n\nimport {IMarketAdapter} from '../../interfaces/adapter/IMarketAdapter.sol';\nimport {IACLManager} from '../../interfaces/IACLManager.sol';\n\nimport {BaseEmergency} from '../../libraries/base/BaseEmergency.sol';\nimport {Errors} from '../../libraries/helpers/Errors.sol';\nimport {DataTypes} from '../../types/DataTypes.sol';\n\ncontract ReservoirAdapter is BaseEmergency, IMarketAdapter {\n  using SafeERC20 for IERC20;\n  using Address for address;\n  address private immutable RESERVOIR;\n  address private immutable ETH_RESERVOIR;\n\n  ///////////////////////////////////////////////\n  // MODIFIERS\n  ///////////////////////////////////////////////\n\n  modifier onlyProtocol() {\n    if (!IACLManager(_aclManager).isProtocol(msg.sender)) {\n      revert Errors.AccessDenied();\n    }\n    _;\n  }\n\n  constructor(address aclManager, address reservoir, address eth) BaseEmergency(aclManager) {\n    RESERVOIR = reservoir;\n    ETH_RESERVOIR = eth;\n  }\n\n  function preSell(PreSellParams memory params) public payable onlyProtocol {\n    IProtocolOwner(params.protocolOwner).approveSale(\n      params.collection,\n      params.tokenId,\n      params.underlyingAsset,\n      params.marketPrice,\n      params.marketApproval,\n      params.loanId\n    );\n  }\n\n  function sell(SellParams memory params) public payable onlyProtocol {\n    IProtocolOwner(params.protocolOwner).execTransaction(\n      params.to,\n      params.value,\n      params.data,\n      0,\n      0,\n      0,\n      address(0),\n      payable(0)\n    );\n    // We move the funds from the wallet to the sender\n    IERC20(params.underlyingAsset).safeTransferFrom(params.wallet, msg.sender, params.marketPrice);\n  }\n\n  function preBuy(PreBuyParams memory params) public payable onlyProtocol {\n    // NOTHING TO DO\n  }\n\n  function buy(BuyParams memory params) public payable onlyProtocol returns (uint256) {\n    uint256 initialBalance = _getBalance(params.underlyingAsset);\n    // Make the approval\n    if (params.underlyingAsset != ETH_RESERVOIR) {\n      IERC20(params.underlyingAsset).approve(params.marketApproval, params.marketPrice);\n    }\n    // Run the transaction\n    _rawExec(params.to, params.value, params.data);\n    // Calcualte end balance\n    uint256 endBalance = _getBalance(params.underlyingAsset);\n    // Calculate real cost\n    uint256 realCost = initialBalance - endBalance;\n\n    return realCost;\n  }\n\n  function _rawExec(address to, uint256 value, bytes memory data) private {\n    // Ensure the target is a contract\n    (bool sent, ) = payable(to).call{value: value}(data);\n    if (sent == false) revert Errors.UnsuccessfulExecution();\n  }\n\n  function _getBalance(address currency) internal view returns (uint256) {\n    if (currency == ETH_RESERVOIR) {\n      return address(this).balance;\n    }\n    return IERC20(currency).balanceOf(address(this));\n  }\n\n  receive() external payable {}\n\n  fallback() external payable {}\n}\n"
      },
      "src/types/DataTypes.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\nimport {Constants} from '../libraries/helpers/Constants.sol';\n\n\nlibrary DataTypes {\n\n  ///////////////////////////////////////////////////////\n  // ASSET \n  ///////////////////////////////////////////////////////\n\n  struct MarketBalance {\n  // Total supply invested\n    uint128 totalSupplyScaledNotInvested;   \n    // Total supply\n    uint128 totalSupplyAssets;\n    uint128 totalSupplyScaled;\n    // Total supply borrowed\n    uint128 totalBorrowScaled;\n      // last update\n    uint40 lastUpdateTimestamp;\n  }\n\n  struct ReserveData {\n    ReserveConfigurationMap config;\n    //the liquidity index. Expressed in ray\n    uint128 liquidityIndex;\n    //variable borrow index. Expressed in ray\n    uint128 variableBorrowIndex;\n    //the current supply rate. Expressed in ray\n    uint128 currentLiquidityRate;\n    //the current variable borrow rate. Expressed in ray\n    uint128 currentVariableBorrowRate;\n    // address asset\n    address underlyingAsset;\n    // address scaled token\n    address scaledTokenAddress;\n    //address of the interest rate strategy\n    address interestRateAddress;\n    // address of the strategy\n    address strategyAddress;\n    // last update\n    uint40 lastUpdateTimestamp;\n  }\n  \n  struct ReserveConfigurationMap {\n    //bit 0-15: LTV\n    //bit 16-31: Liq. threshold\n    //bit 32-47: Liq. bonus\n    //bit 48-55: Decimals\n    //bit 56: reserve is active\n    //bit 57: reserve is frozen\n    //bit 58: borrowing is enabled\n    //bit 59: stable rate borrowing enabled\n    //bit 60: asset is paused\n    //bit 61: borrowing in isolation mode is enabled\n    //bit 62: siloed borrowing enabled\n    //bit 63: flashloaning enabled\n    //bit 64-79: reserve factor\n    //bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap\n    //bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap\n    //bit 152-167 liquidation protocol fee\n    //bit 168-175 eMode category\n    //bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled\n    //bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals\n    //bit 252-255 unused\n\n    uint256 data;\n  }\n\n   \n\n  ///////////////////////////////////////////////////////\n  // ORDER \n  ///////////////////////////////////////////////////////\n\n  struct OfferItem {\n    // Slot 0\n    bytes32 loanId;\n    // Slot 1\n    bytes32 assetId;\n    // Slot 2\n    uint128 startAmount;\n    uint128 endAmount; \n    // Slot 3\n    uint128 debtToSell;\n  }  \n\n  struct Timeframe {\n    // Slot 0\n    uint40 startTime;\n    uint40 endTime;\n  }\n\n  struct Bid {\n    // Slot 0\n    bytes32 loanId;\n    // Slot 1\n    address buyer;\n    // Slot 2\n    uint128 amountToPay;\n    uint128 amountOfDebt;\n  }\n\n  struct Order {\n    // Slot 0\n    bytes32 orderId;\n    // Slot 1\n    address owner;\n    Constants.OrderType orderType;\n    uint88 countBids;\n\n    uint256 bidderDebtPayed;\n    uint256 bidderBonus;\n    // Slot 2\n    OfferItem offer;\n    // Slot 3\n    Timeframe timeframe;\n    // Slot 4\n    Bid bid;\n  }\n\n  ///////////////////////////////////////////////////////\n  // LOAN \n  ///////////////////////////////////////////////////////\n\n  struct Loan {\n    // Slot 0\n    bytes32 loanId;\n    // Slot 1\n    uint88 totalAssets;\n    Constants.LoanState state;\n    // Slot 2\n    address underlyingAsset;\n    // Slot 3\n    address owner; \n  }\n\n\n  ///////////////////////////////////////////////////////\n  // Asset\n  ///////////////////////////////////////////////////////\n\n  struct Asset {\n    address collection;\n    uint256 tokenId;\n  }\n \n  ///////////////////////////////////////////////////////\n  // SIGNATURES \n  ///////////////////////////////////////////////////////\n\n  struct EIP712Signature {\n    uint8 v;\n    bytes32 r;\n    bytes32 s;\n    uint256 deadline;\n  }\n\n  struct SignLoanConfig {\n    bytes32 loanId;\n    uint256 aggLoanPrice;\n    uint256 aggLtv;\n    uint256 aggLiquidationThreshold;\n    uint88 totalAssets;\n    uint256 nonce;\n    uint256 deadline;\n  }\n\n  struct SignAsset {\n    bytes32 assetId;\n    address collection;\n    uint256 tokenId;\n    uint256 price;\n    uint256 nonce;\n    uint256 deadline;\n  }\n\n  struct SignBuyNow {\n    SignAsset asset;\n    uint256 assetLtv; // configuration asset\n    uint256 assetLiquidationThreshold; // configuration asset\n    // tx Data\n    address from;\n    address to;\n    bytes data;\n    uint256 value;\n    // Configuration\n    address marketAdapter;\n    address marketApproval; // Approval needed to make the buy\n    uint256 marketPrice; // Market Adapter Price (Reservoir, Opensea ...)\n    address underlyingAsset; // asset needed to buy\n    uint256 nonce;\n    uint256 deadline;\n  }\n\n  struct SignSellNow {\n    SignLoanConfig loan;\n    bytes32 assetId;\n    // approval\n    address marketAdapter;\n    address marketApproval;\n    uint256 marketPrice;\n    address underlyingAsset;\n    // sell data\n    address from;\n    address to;\n    bytes data;\n    uint256 value;\n  \n    // signature\n    uint256 nonce;\n    uint256 deadline;\n  }\n\n  struct SignAction {\n    SignLoanConfig loan;\n    bytes32[] assets;\n    address underlyingAsset;\n    uint256 nonce;\n    uint256 deadline;\n  }\n\n  struct SignMarket {\n    SignLoanConfig loan;\n    bytes32 assetId;\n    address collection;\n    uint256 tokenId;\n    uint256 assetPrice;\n    uint256 assetLtv;\n    uint256 nonce;\n    uint256 deadline;\n  }\n\n  struct SignAuction {\n    SignLoanConfig loan;\n    bytes32[] assets;\n    uint256 assetPrice;\n    uint256 assetLtv;\n    uint40 endTime; // @audit-info review this\n    uint256 nonce;\n    uint256 deadline;\n  }\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"
  }}