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"
      },
      "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/tokens/IInterestRate.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\n/**\n * @title IInterestRate interface\n * @dev Interface for the calculation of the interest rates\n * @author Unlockd\n */\ninterface IInterestRate {\n  struct CalculateInterestRatesParams {\n    uint256 liquidityAdded;\n    uint256 liquidityTaken;\n    uint256 totalVariableDebt;\n    uint256 totalSupplyAssets;\n    uint256 reserveFactor;\n  }\n\n  /**\n   * @dev Get the variable borrow rate\n   * @return the base variable borrow rate\n   *\n   */\n  function baseVariableBorrowRate() external view returns (uint256);\n\n  /**\n   * @dev Get the maximum variable borrow rate\n   * @return the maximum variable borrow rate\n   *\n   */\n  function getMaxVariableBorrowRate() external view returns (uint256);\n\n  /**\n   * @dev Calculates the interest rates depending on the reserve's state and configurations\n   * @param params params needed to calculate the interest rate\n   */\n  function calculateInterestRates(\n    CalculateInterestRatesParams memory params\n  ) external view returns (uint256, uint256);\n\n  /**\n   * @dev Calculates the interest rates depending on the reserve's state and configurations\n   * @param availableLiquidity The available liquidity for the reserve\n   * @param totalVariableDebt The total borrowed from the reserve at a variable rate\n   * @param reserveFactor The reserve portion of the interest that goes to the treasury of the market\n   *\n   */\n  function calculateInterestRates(\n    uint256 availableLiquidity,\n    uint256 totalVariableDebt,\n    uint256 reserveFactor\n  ) external view returns (uint256 currentLiquidityRate, uint256 currentVariableBorrowRate);\n}\n"
      },
      "src/libraries/base/InterestRate.sol": {
        "content": "// SPDX-License-Identifier: BUSL-1.1\npragma solidity 0.8.19;\n\nimport {IInterestRate} from '../../interfaces/tokens/IInterestRate.sol';\nimport {WadRayMath} from '../math/WadRayMath.sol';\nimport {PercentageMath} from '../math/PercentageMath.sol';\nimport {Errors} from '../helpers/Errors.sol';\nimport {DataTypes} from '../../types/DataTypes.sol';\nimport {IACLManager} from '../../interfaces/IACLManager.sol';\n\n/**\n\n * @title InterestRate contract\n * @notice Implements the calculation of the interest rates depending on the reserve state\n * @dev The model of interest rate is based on 2 slopes, one before the `OPTIMAL_UTILIZATION_RATE`\n * point of utilization and another from that one to 100%\n * @dev based on Aave InterestRate https://github.com/aave/aave-v3-core/blob/master/contracts/misc/ZeroReserveInterestRateStrategy.sol\n * @author Unlockd\n *\n */\ncontract InterestRate is IInterestRate {\n  using WadRayMath for uint256;\n  using PercentageMath for uint256;\n\n  address public immutable _aclManager;\n\n  modifier onlyAdmin() {\n    if (!IACLManager(_aclManager).isUTokenAdmin(msg.sender)) {\n      revert Errors.UTokenAccessDenied();\n    }\n    _;\n  }\n\n  /**\n   * @dev this constant represents the utilization rate at which the pool aims to obtain most competitive borrow rates.\n   * Expressed in ray\n   *\n   */\n  uint256 public OPTIMAL_UTILIZATION_RATE;\n\n  /**\n   * @dev This constant represents the excess utilization rate above the optimal. It's always equal to\n   * 1-optimal utilization rate. Added as a constant here for gas optimizations.\n   * Expressed in ray\n   *\n   */\n\n  uint256 public EXCESS_UTILIZATION_RATE;\n\n  // Base variable borrow rate when Utilization rate = 0. Expressed in ray\n  uint256 internal _baseVariableBorrowRate;\n\n  // Slope of the variable interest curve when utilization rate > 0 and <= OPTIMAL_UTILIZATION_RATE. Expressed in ray\n  uint256 internal _variableRateSlope1;\n\n  // Slope of the variable interest curve when utilization rate > OPTIMAL_UTILIZATION_RATE. Expressed in ray\n  uint256 internal _variableRateSlope2;\n\n  constructor(\n    address aclManager,\n    uint256 optimalUtilizationRate_,\n    uint256 baseVariableBorrowRate_,\n    uint256 variableRateSlope1_,\n    uint256 variableRateSlope2_\n  ) {\n    _aclManager = aclManager;\n    OPTIMAL_UTILIZATION_RATE = optimalUtilizationRate_;\n    EXCESS_UTILIZATION_RATE = WadRayMath.ray() - (optimalUtilizationRate_);\n    _baseVariableBorrowRate = baseVariableBorrowRate_;\n    _variableRateSlope1 = variableRateSlope1_;\n    _variableRateSlope2 = variableRateSlope2_;\n  }\n\n  function variableRateSlope1() external view returns (uint256) {\n    return _variableRateSlope1;\n  }\n\n  function variableRateSlope2() external view returns (uint256) {\n    return _variableRateSlope2;\n  }\n\n  /**\n   * @dev Get the variable borrow rate\n   * @return the base variable borrow rate\n   *\n   */\n  function baseVariableBorrowRate() external view returns (uint256) {\n    return _baseVariableBorrowRate;\n  }\n\n  /**\n   * @dev Get the maximum variable borrow rate\n   * @return the maximum variable borrow rate\n   *\n   */\n  function getMaxVariableBorrowRate() external view returns (uint256) {\n    return _baseVariableBorrowRate + (_variableRateSlope1) + (_variableRateSlope2);\n  }\n\n  /**\n   * @dev Calculates the interest rates depending on the reserve's state and configurations\n   * @return The liquidity rate, the stable borrow rate and the variable borrow rate\n   *\n   */\n  function calculateInterestRates(\n    CalculateInterestRatesParams memory params\n  ) external view returns (uint256, uint256) {\n    //avoid stack too deep\n    uint256 availableLiquidity = params.totalSupplyAssets +\n      (params.liquidityAdded) -\n      (params.liquidityTaken);\n    return\n      calculateInterestRates(availableLiquidity, params.totalVariableDebt, params.reserveFactor);\n  }\n\n  struct CalcInterestRatesLocalVars {\n    uint256 totalDebt;\n    uint256 currentVariableBorrowRate;\n    uint256 currentLiquidityRate;\n    uint256 utilizationRate;\n  }\n\n  /**\n   * @dev Calculates the interest rates depending on the reserve's state and configurations.\n   * NOTE This function is kept for compatibility with the previous DefaultInterestRateStrategy interface.\n   * New protocol implementation uses the new calculateInterestRates() interface\n   * @param availableLiquidity The liquidity available in the corresponding uToken\n   * @param totalVariableDebt The total borrowed from the reserve at a variable rate\n   * @param reserveFactor The reserve portion of the interest that goes to the treasury of the market\n   * @return currentLiquidityRate The liquidity rate\n   * @return currentVariableBorrowRate The variable borrow rate\n   *\n   */\n  function calculateInterestRates(\n    uint256 availableLiquidity,\n    uint256 totalVariableDebt,\n    uint256 reserveFactor\n  ) public view returns (uint256 currentLiquidityRate, uint256 currentVariableBorrowRate) {\n    uint256 utilizationRate = totalVariableDebt == 0\n      ? 0\n      : totalVariableDebt.rayDiv(availableLiquidity + (totalVariableDebt));\n\n    if (utilizationRate > OPTIMAL_UTILIZATION_RATE) {\n      uint256 excessUtilizationRateRatio;\n      unchecked {\n        excessUtilizationRateRatio =\n          utilizationRate -\n          (OPTIMAL_UTILIZATION_RATE).rayDiv(EXCESS_UTILIZATION_RATE);\n      }\n      currentVariableBorrowRate =\n        _baseVariableBorrowRate +\n        (_variableRateSlope1) +\n        (_variableRateSlope2.rayMul(excessUtilizationRateRatio));\n    } else {\n      currentVariableBorrowRate =\n        _baseVariableBorrowRate +\n        (utilizationRate.rayMul(_variableRateSlope1).rayDiv(OPTIMAL_UTILIZATION_RATE));\n    }\n\n    currentLiquidityRate = _getOverallBorrowRate(totalVariableDebt, currentVariableBorrowRate)\n      .rayMul(utilizationRate)\n      .percentMul(PercentageMath.PERCENTAGE_FACTOR - (reserveFactor));\n  }\n\n  /**\n   * @dev Calculates the overall borrow rate as the weighted average between the total variable debt and total stable debt\n   * @param totalVariableDebt The total borrowed from the reserve at a variable rate\n   * @param currentVariableBorrowRate The current variable borrow rate of the reserve\n   * @return overallBorrowRate The weighted averaged borrow rate\n   *\n   */\n  function _getOverallBorrowRate(\n    uint256 totalVariableDebt,\n    uint256 currentVariableBorrowRate\n  ) internal pure returns (uint256 overallBorrowRate) {\n    if (totalVariableDebt == 0) return 0;\n\n    uint256 weightedVariableRate = totalVariableDebt.wadToRay().rayMul(currentVariableBorrowRate);\n\n    overallBorrowRate = weightedVariableRate.rayDiv(totalVariableDebt.wadToRay());\n  }\n\n  function configInterestRate(\n    uint256 optimalUtilizationRate_,\n    uint256 baseVariableBorrowRate_,\n    uint256 variableRateSlope1_,\n    uint256 variableRateSlope2_\n  ) public onlyAdmin {\n    OPTIMAL_UTILIZATION_RATE = optimalUtilizationRate_;\n    EXCESS_UTILIZATION_RATE = WadRayMath.ray() - (optimalUtilizationRate_);\n    _baseVariableBorrowRate = baseVariableBorrowRate_;\n    _variableRateSlope1 = variableRateSlope1_;\n    _variableRateSlope2 = variableRateSlope2_;\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/libraries/math/PercentageMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * @title PercentageMath library\n * @author Unlockd\n * @notice Provides functions to perform percentage calculations\n * @dev Percentages are defined by default with 2 decimals of precision (100.00). The precision is indicated by PERCENTAGE_FACTOR\n * @dev Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down.\n * @dev fork from https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/math/PercentageMath.sol\n */\nlibrary PercentageMath {\n  uint256 constant PERCENTAGE_FACTOR = 1e4; //percentage plus two decimals\n  uint256 constant ONE_HUNDRED_PERCENT = 1e4; //10000, 100%\n  uint256 internal constant HALF_PERCENTAGE_FACTOR = 0.5e4;\n\n  /**\n   * @notice Executes a percentage multiplication\n   * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328\n   * @param value The value of which the percentage needs to be calculated\n   * @param percentage The percentage of the value to be calculated\n   * @return result value percentmul percentage\n   */\n  function percentMul(uint256 value, uint256 percentage) internal pure returns (uint256 result) {\n    // to avoid overflow, value <= (type(uint256).max - HALF_PERCENTAGE_FACTOR) / percentage\n    assembly {\n      if iszero(\n        or(\n          iszero(percentage),\n          iszero(gt(value, div(sub(not(0), HALF_PERCENTAGE_FACTOR), percentage)))\n        )\n      ) {\n        revert(0, 0)\n      }\n\n      result := div(add(mul(value, percentage), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR)\n    }\n  }\n\n  /**\n   * @notice Executes a percentage division\n   * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328\n   * @param value The value of which the percentage needs to be calculated\n   * @param percentage The percentage of the value to be calculated\n   * @return result value percentdiv percentage\n   */\n  function percentDiv(uint256 value, uint256 percentage) internal pure returns (uint256 result) {\n    // to avoid overflow, value <= (type(uint256).max - halfPercentage) / PERCENTAGE_FACTOR\n    assembly {\n      if or(\n        iszero(percentage),\n        iszero(iszero(gt(value, div(sub(not(0), div(percentage, 2)), PERCENTAGE_FACTOR))))\n      ) {\n        revert(0, 0)\n      }\n\n      result := div(add(mul(value, PERCENTAGE_FACTOR), div(percentage, 2)), percentage)\n    }\n  }\n}\n"
      },
      "src/libraries/math/WadRayMath.sol": {
        "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.19;\n\n/**\n * @title WadRayMath library\n * @author Unlockd\n * @notice Provides functions to perform calculations with Wad and Ray units\n * @dev Provides mul and div function for wads (decimal numbers with 18 digits of precision) and rays (decimal numbers\n * with 27 digits of precision)\n * @dev Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down.\n * @dev fork from https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/math/WadRayMath.sol\n */\nlibrary WadRayMath {\n  // HALF_WAD and HALF_RAY expressed with extended notation as constant with operations are not supported in Yul assembly\n  uint256 internal constant WAD = 1e18;\n  uint256 internal constant HALF_WAD = 0.5e18; // 18\n\n  uint256 internal constant RAY = 1e27;\n  uint256 internal constant HALF_RAY = 0.5e27; // A Ray is a unit with 27 decimals of precision.\n\n  uint256 internal constant WAD_RAY_RATIO = 1e9;\n\n  /**\n   * @return One ray, 1e27\n   *\n   */\n  function ray() internal pure returns (uint256) {\n    return RAY;\n  }\n\n  /**\n   * @return One wad, 1e18\n   *\n   */\n\n  function wad() internal pure returns (uint256) {\n    return WAD;\n  }\n\n  /**\n   * @return Half ray, 1e27/2\n   *\n   */\n  function halfRay() internal pure returns (uint256) {\n    return HALF_RAY;\n  }\n\n  /**\n   * @return Half ray, 1e18/2\n   *\n   */\n  function halfWad() internal pure returns (uint256) {\n    return HALF_WAD;\n  }\n\n  /**\n   * @dev Solady FixedPointMathLib.sol mulWad (Equivalent to `(x * y) / WAD` rounded up.)\n   * @param x Wad\n   * @param y Wad\n   * @return z = x*y, in wad\n   */\n  function wadMul(uint256 x, uint256 y) internal pure returns (uint256 z) {\n    /// @solidity memory-safe-assembly\n    assembly {\n      // Equivalent to `require(y == 0 || x <= type(uint256).max / y)`.\n      if mul(y, gt(x, div(not(0), y))) {\n        mstore(0x00, 0xbac65e5b) // `MulWadFailed()`.\n        revert(0x1c, 0x04)\n      }\n      z := div(mul(x, y), WAD)\n    }\n  }\n\n  /**\n   * @dev Solady FixedPointMathLib.sol divWad (Equivalent to `(x * WAD) / y` rounded down.)\n   * @param x Wad\n   * @param y Wad\n   * @return z = z/y, in wad\n   */\n  function wadDiv(uint256 x, uint256 y) internal pure returns (uint256 z) {\n    /// @solidity memory-safe-assembly\n    assembly {\n      // Equivalent to `require(y != 0 && (WAD == 0 || x <= type(uint256).max / WAD))`.\n      if iszero(mul(y, iszero(mul(WAD, gt(x, div(not(0), WAD)))))) {\n        mstore(0x00, 0x7c5f487d) // `DivWadFailed()`.\n        revert(0x1c, 0x04)\n      }\n      z := div(mul(x, WAD), y)\n    }\n  }\n\n  /**\n   * @notice Multiplies two ray, rounding half up to the nearest ray\n   * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328\n   * @param a Ray\n   * @param b Ray\n   * @return c = a raymul b\n   */\n  function rayMul(uint256 a, uint256 b) internal pure returns (uint256 c) {\n    // to avoid overflow, a <= (type(uint256).max - HALF_RAY) / b\n    assembly {\n      if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_RAY), b))))) {\n        revert(0, 0)\n      }\n\n      c := div(add(mul(a, b), HALF_RAY), RAY)\n    }\n  }\n\n  /**\n   * @notice Divides two ray, rounding half up to the nearest ray\n   * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328\n   * @param a Ray\n   * @param b Ray\n   * @return c = a raydiv b\n   */\n  function rayDiv(uint256 a, uint256 b) internal pure returns (uint256 c) {\n    // to avoid overflow, a <= (type(uint256).max - halfB) / RAY\n    assembly {\n      if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), RAY))))) {\n        revert(0, 0)\n      }\n\n      c := div(add(mul(a, RAY), div(b, 2)), b)\n    }\n  }\n\n  /**\n   * @dev Casts ray down to wad\n   * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328\n   * @param a Ray\n   * @return b = a converted to wad, rounded half up to the nearest wad\n   */\n  function rayToWad(uint256 a) internal pure returns (uint256 b) {\n    assembly {\n      b := div(a, WAD_RAY_RATIO)\n      let remainder := mod(a, WAD_RAY_RATIO)\n      if iszero(lt(remainder, div(WAD_RAY_RATIO, 2))) {\n        b := add(b, 1)\n      }\n    }\n  }\n\n  /**\n   * @dev Converts wad up to ray\n   * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328\n   * @param a Wad\n   * @return b = a converted in ray\n   */\n  function wadToRay(uint256 a) internal pure returns (uint256 b) {\n    // to avoid overflow, b/WAD_RAY_RATIO == a\n    assembly {\n      b := mul(a, WAD_RAY_RATIO)\n\n      if iszero(eq(div(b, WAD_RAY_RATIO), a)) {\n        revert(0, 0)\n      }\n    }\n  }\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"
  }}