# OrderBook

## Order Book

> Order Book uses Diamond proxy pattern. There are three important facets from the user perspective.
>
> * OrderBookBuyFacet
> * OrderBookSellFacet
> * OrderBookCancelFacet
> * OrderBookGeneralFacet

## OrderBookBuyFacet

> Order Book Buy Facet - Allows to create buy trades between two, defined tokens compatible with ERC-20.

*.Contract uses double linked list to store new buys and sells items*

### OrderBookBuyFacet - Methods

#### newBuyOrder

```solidity
function newBuyOrder(bytes orderData, bytes reportingData, bytes crossIdentifier) external nonpayable
```

* Function creates new buy order,
* orderData param must fit structure,
* this function has multiple executing scenarios depending on the current state of order book,
* transfers collateral from the client address to the order book or seller address
* only executable when contract is not paused
* only executable when not called by the admin
* reentrancy protected
* does not follow Checks-Effects-Interactions pattern
* for detailed explanation of orderData structure check the corresponding documentation

**Parameters**

| Name            | Type  | Description                                                                                                   |
| --------------- | ----- | ------------------------------------------------------------------------------------------------------------- |
| orderData       | bytes | New buy order data (Bits: buyQuantity 64 \| buyPrice 64 \| orderType 8 \| executionCondition 8 \| lifetime 8) |
| reportingData   | bytes | (Bits: ownerReportingId 32 \| decisionReportingId 32)                                                         |
| crossIdentifier | bytes | any unique identifier or empty                                                                                |

## OrderBookSellFacet

> Order Book - Allows to create sell trades between two, defined tokens compatible with ERC-20.

*Contract uses double linked list to store new buys and sells items*

### OrderBookSellFacet - Methods

#### newSellOrder

```solidity
function newSellOrder(bytes orderData, bytes reportingData, bytes crossIdentifier) external nonpayable
```

* Function creates new sell order
* orderData param must fit structure,
* this function has multiple executing scenarios depending on the current state of order book,
* transfers collateral from the client address to the order book or seller address
* only executable when contract is not paused
* only executable when not called by the admin
* reentrancy protected
* does not follow Checks-Effects-Interactions pattern
* for detailed explanation of orderData structure check the corresponding documentation

**Parameters**

| Name            | Type  | Description                                                                                                   |
| --------------- | ----- | ------------------------------------------------------------------------------------------------------------- |
| orderData       | bytes | New buy order data (Bits: buyQuantity 64 \| buyPrice 64 \| orderType 8 \| executionCondition 8 \| lifetime 8) |
| reportingData   | bytes | (Bits: ownerReportingId 32 \| decisionReportingId 32)                                                         |
| crossIdentifier | bytes | any unique identifier or empty                                                                                |

## OrderBookCancelFacet

> Order Book Cancel Facet - Allows to cancel order based on provided orderId

*Contract handles cancels for buy and sell orders*

### OrderBookCancelFacet - Methods

#### cancelBuyOrder

```solidity
function cancelBuyOrder(uint64 orderId) external nonpayable
```

* Function cancels given buy order based on provided id
* Cancels buy order with given id. Transfers back collateral to the client address.
* only executable when market is not closed and will cancel only if executed by order owner (client address)
* reverts if orderId does not exist
* follows Checks-Effects-Interactions pattern

**Parameters**

| Name    | Type   | Description        |
| ------- | ------ | ------------------ |
| orderId | uint64 | Order id to cancel |

#### cancelSellOrder

```solidity
function cancelSellOrder(uint64 orderId) external nonpayable
```

* Function cancels given sell order based on provided idCancels sell order with given id.
* Transfers back collateral to the client address.
* only executable when market is not closed and will cancel only if executed by order owner (client address)
* reverts when orderId does not exist
* follows Checks-Effects-Interactions pattern\*

**Parameters**

| Name    | Type   | Description        |
| ------- | ------ | ------------------ |
| orderId | uint64 | Order id to cancel |

## OrderBookGeneralFacet

> Order Book General Facet - Allows to query order book for publicly available properties.

*Contract mostly returns some useful values around order book*

### OrderBookGeneralFacet - Methods

#### bestBidOffer

```solidity
function bestBidOffer() external view returns (uint256)
```

* Return best bid offer and best ask offer

*best buy = 128 bits (64 quantity | 64 price) | best sell = 128 bits (64 quantity | 64 price)*

**Returns**

| Name | Type    | Description                 |
| ---- | ------- | --------------------------- |
| \_0  | uint256 | Returns best bid\&ask offer |

#### bestFiftyOffers

```solidity
function bestFiftyOffers() external view returns (uint256[], uint256[])
```

* Return up to best 50 bids and asksIf there is less than 50 orders in either buy or sell side element 0 will be returned but \* arrays returned will always be fixed size

*Description about returned variables- tuple with 2 arrays, with fixed size of 50 elements- (best\_bids\[50], best\_asks\[50])- each element represents order data (quantity and price)- each order is a 256 bit unsigned integer, bits 0...63 represents price, 64...127 quantity*

**Returns**

| Name | Type       | Description                |
| ---- | ---------- | -------------------------- |
| \_0  | uint256\[] | bids array of best 50 bids |
| \_1  | uint256\[] | asks array of best 50 asks |

#### countBuyOrders

```solidity
function countBuyOrders() external view returns (uint256)
```

* Function counts active buy orders in the order book

**Returns**

| Name | Type    | Description                            |
| ---- | ------- | -------------------------------------- |
| \_0  | uint256 | Returns count of all active buy orders |

#### countSellOrders

```solidity
function countSellOrders() external view returns (uint256)
```

* Function counts active sell orders in the order book

**Returns**

| Name | Type    | Description                             |
| ---- | ------- | --------------------------------------- |
| \_0  | uint256 | Returns count of all active sell orders |

#### getConfig

```solidity
function getConfig() external view returns (struct LibOrderBookStructs.OrderBookConfig)
```

*Retrieves the configuration settings.*

**Returns**

| Name | Type                                | Description                 |
| ---- | ----------------------------------- | --------------------------- |
| \_0  | LibOrderBookStructs.OrderBookConfig | The configuration settings. |

* Returned structure has following fields:

```
  struct OrderBookConfig {
    Scales scales;
    uint64 makerCommission;
    uint64 takerCommission;
    uint64 marketMakerCommission;
    address quoteToken;
    address baseToken;
    address whitelist;
    address commissionWallet;
    address baseTokenFallbackWallet;
    address quoteTokenFallbackWallet;
    uint8 liquidityBand; 
    bytes11 version;
  }

  struct Scales {
    TokenScales base;
    TokenScales quote;
  }

  struct TokenScales {
    uint128 nonNative;
    uint128 native;
  }
```

| Name                     | Type    | Description                                                                      |
| ------------------------ | ------- | -------------------------------------------------------------------------------- |
| scales                   | struct  | holds information about scales for base and quote tokens                         |
| makerCommission          | uint64  | maker commission (fee)                                                           |
| takerCommission          | uint64  | taker commission (fee)                                                           |
| marketMakerCommission    | uint64  | market maker commission (fee)                                                    |
| quoteToken               | address | quote token contract address                                                     |
| baseToken                | address | base token contract address                                                      |
| whitelist                | address | whitelist contract address                                                       |
| commissionWallet         | address | account where all fees are transferred                                           |
| baseTokenFallbackWallet  | address | account where funds are held if it was not possible to transfer it to the owner  |
| quoteTokenFallbackWallet | address | account where funds are held if it was not possible to transfer it to the ownere |
| liquidityBand            | uint8   | liquidity band to be compliant with ESMA                                         |
| version                  | bytes11 | version of the smart contract                                                    |

#### getLiquidityBand

```solidity
function getLiquidityBand() external view returns (uint8)
```

**Returns**

| Name | Type  | Description                              |
| ---- | ----- | ---------------------------------------- |
| \_0  | uint8 | Liquidity band - in compliance with ESMA |

#### getOrderBookPhase

```solidity
function getOrderBookPhase() external view returns (enum LibEnums.OrderBookPhases)
```

* Method informs about current Order Book phase

**Returns**

| Name | Type                          | Description   |
| ---- | ----------------------------- | ------------- |
| \_0  | enum LibEnums.OrderBookPhases | current phase |

* Returned enum has following fields:

```
  enum OrderBookPhases {
    None, /// * The initial state before the order book is opened
    OpenForTrading, /// * The order book is open and orders can be placed and filled
    ClosedForTrading, /// * The order book is closed and no trading can occur
    ManualHalt, /// * Trading is halted manually by an administrator or owner
    AutomaticHalt /// *Trading is halted automatically due to predefined conditions
  }
```

#### getOrderDetails

```solidity
function getOrderDetails(uint64 orderId) external view returns (struct LibOrderBookStructs.Order)
```

**Parameters**

| Name    | Type   | Description                                  |
| ------- | ------ | -------------------------------------------- |
| orderId | uint64 | Order id established during placing an order |

**Returns**

| Name | Type                      | Description               |
| ---- | ------------------------- | ------------------------- |
| \_0  | LibOrderBookStructs.Order | struct with order details |

* Retunrned structure has following fields:

```
  struct Order {
    uint256 timestamp;
    uint64 quantity; 
    uint64 price;   
    uint64 clientId;
    uint64 orderId;
    uint64 prevOrderId;
    uint64 nextOrderId;
    uint32 crossIdentifier;
    LibEnums.OrderKind orderKind;
    uint8 lifetime;
  }
```

| Name            | Type    | Description                                                               |
| --------------- | ------- | ------------------------------------------------------------------------- |
| timestamp       | uint256 | timestamp of an order, when it was placed                                 |
| quantity        | uint64  | quantity of an order                                                      |
| price           | uint64  | price of an order                                                         |
| clientId        | uint64  | client identifier, assigned by whitelist contract                         |
| orderId         | uint64  | order identifier, assigned by order book                                  |
| prevOrderId     | uint64  | prev order id in the order book                                           |
| nextOrderId     | uint64  | next order Id in the order book                                           |
| crossIdentifier | uint32  | cross identifier which helps distinguish orders from the same party       |
| orderKind       | enum    | kept information about an order if it was BUY or SELL                     |
| lifetime        | uint8   | lifetime of an order in days, used for Good till date execution condition |

#### getPreTradeControlConfig

```solidity
function getPreTradeControlConfig() external view returns (struct LibOrderBookControl.OrderBookPreTradeStorage)
```

*Retrieves the current pre-trade control configuration.*

**Returns**

| Name | Type                                         | Description                          |
| ---- | -------------------------------------------- | ------------------------------------ |
| \_0  | LibOrderBookControl.OrderBookPreTradeStorage | The pre-trade control configuration. |

* Returned structure has following fields:

```
  struct OrderBookPreTradeStorage {
    uint256 maxValue;
    uint128 minValue;
    uint64 priceCollarFactor;
    uint64 maxMatches;
  }
```

| Name              | Type    | Description                                                    |
| ----------------- | ------- | -------------------------------------------------------------- |
| maxValue          | uint256 | maximum value of an order that can be placed                   |
| minValue          | uint128 | minimum value of an order that can be placed                   |
| priceCollarFactor | uint64  | multiplier used during pre trade controls                      |
| maxMatches        | uint64  | maximum number of matches that can happen with one transaction |

#### getStaticRefPrice

```solidity
function getStaticRefPrice() external view returns (uint64)
```

*Retrieves the current static reference price.*

**Returns**

| Name | Type   | Description                 |
| ---- | ------ | --------------------------- |
| \_0  | uint64 | The static reference price. |

#### getVolatilityManagementConfig

```solidity
function getVolatilityManagementConfig() external view returns (struct LibOrderBookControl.VolatilityManagementStorage)
```

*Retrieves the current volatility management configuration.*

**Returns**

| Name | Type                                            | Description                              |
| ---- | ----------------------------------------------- | ---------------------------------------- |
| \_0  | LibOrderBookControl.VolatilityManagementStorage | The volatility management configuration. |

* Returned structure has following fields:

```
  struct VolatilityManagementStorage {
    uint64 dynamicRefPrice; 
    uint64 staticThreshold;
    uint64 dynamicThreshold;
    bool isDynamicCheckEnabled;
  }
```

| Name                  | Type   | Description                                                                       |
| --------------------- | ------ | --------------------------------------------------------------------------------- |
| dynamicRefPrice       | uint64 | The dynamic reference price considered also as last execution price on the market |
| staticThreshold       | uint64 | prevents drastic changes on the market, provided as a percentage value.           |
| dynamicThreshold      | uint64 | prevents drastic changes on the market, provided as a percentage value            |
| isDynamicCheckEnabled | bool   | configuration flag responsible for checking dynamic reference price               |

### OrderBook - Events

#### NewBuyInitiatedTrade

```solidity
event NewBuyInitiatedTrade(address indexed buyer, address indexed seller, uint256 fromQuantity, uint256 toQuantity, uint64 price, uint64 indexed sellOrderId, uint256 buyerCommission, uint256 sellerCommission, uint64 tradeSeq, uint64 incomingBuyOrderId)
```

* Event emitted after new buy is initiated

**Parameters**

| Name                  | Type    | Description                                          |
| --------------------- | ------- | ---------------------------------------------------- |
| buyer `indexed`       | address | Buyer address                                        |
| seller `indexed`      | address | Seller address                                       |
| fromQuantity          | uint256 | From quantity                                        |
| toQuantity            | uint256 | To quantity                                          |
| price                 | uint64  | Price of trade                                       |
| sellOrderId `indexed` | uint64  | Sell id                                              |
| buyerCommission       | uint256 | Buyer commission                                     |
| sellerCommission      | uint256 | Seller commission                                    |
| tradeSeq              | uint64  | Tarde sequence number                                |
| incomingBuyOrderId    | uint64  | unique identifier for the order that caused matching |

#### NewBuyOrder

```solidity
event NewBuyOrder(address indexed client, uint64 quantity, uint64 price, uint64 indexed orderId)
```

Event emitted after new buy order is added to list

**Parameters**

| Name              | Type    | Description                              |
| ----------------- | ------- | ---------------------------------------- |
| client `indexed`  | address | Buyer address                            |
| quantity          | uint64  | Quantity of buy order                    |
| price             | uint64  | Price of buy order                       |
| orderId `indexed` | uint64  | OrderId of buy order added by order book |

#### NewSellInitiatedTrade

```solidity
event NewSellInitiatedTrade(address indexed buyer, address indexed seller, uint256 fromQuantity, uint256 toQuantity, uint64 price, uint64 indexed buyOrderId, uint256 buyerCommission, uint256 sellerCommission, uint64 tradeSeq, uint256 reimbursement, uint64 incomingSellOrderId)
```

* Event emitted when sell initiated trade

**Parameters**

| Name                 | Type    | Description                                      |
| -------------------- | ------- | ------------------------------------------------ |
| buyer `indexed`      | address | Buyer of trade                                   |
| seller `indexed`     | address | Seller of trade                                  |
| fromQuantity         | uint256 | From quantity                                    |
| toQuantity           | uint256 | To quantity                                      |
| price                | uint64  | Price of trade                                   |
| buyOrderId `indexed` | uint64  | Buy order id                                     |
| buyerCommission      | uint256 | Buyer commission                                 |
| sellerCommission     | uint256 | Seller commission                                |
| tradeSeq             | uint64  | Trade sequence number                            |
| reimbursement        | uint256 | Reimbursement amount                             |
| incomingSellOrderId  | uint64  | unique identifier of order which caused matching |

#### NewSellOrder

```solidity
event NewSellOrder(address indexed client, uint64 quantity, uint64 price, uint64 indexed orderId)
```

Event emitted after new sell order is added to list

**Parameters**

| Name              | Type    | Description                                |
| ----------------- | ------- | ------------------------------------------ |
| client `indexed`  | address | Client address                             |
| quantity          | uint64  | Quantity of sell order                     |
| price             | uint64  | Price of sell order                        |
| orderId `indexed` | uint64  | Order id of sell order added by order book |

#### OrderReceived

```solidity
event OrderReceived(address indexed client, uint64 indexed orderId, uint64 quantity, uint64 price, enum LibEnums.OrderKind side, bytes reportingData, uint64 crossIdentifier, enum LibEnums.OrderType orderType, enum LibEnums.OrderExecutionCondition executionCondition)
```

Event emitted when new order is received

**Parameters**

| Name               | Type                                  | Description                                                                                            |
| ------------------ | ------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| client `indexed`   | address                               | Client address                                                                                         |
| orderId `indexed`  | uint64                                | unique identifier of an order                                                                          |
| quantity           | uint64                                | Quantity of the order                                                                                  |
| price              | uint64                                | Limit price of the order                                                                               |
| side               | enum LibEnums.OrderKind               | Side of the order - buy / sell                                                                         |
| reportingData      | bytes                                 | Reporting data sent with order                                                                         |
| crossIdentifier    | uint64                                | Cross identifier of the order                                                                          |
| orderType          | enum LibEnums.OrderType               | Type of the order - market / limit                                                                     |
| executionCondition | enum LibEnums.OrderExecutionCondition | execution condition of order i.e GoodForDay, GoodTillDate, BookOrCancel, FillOrKill, ImmediateOrCancel |

#### OrderRejected

```solidity
event OrderRejected(address indexed client, uint64 indexed orderId, uint64 quantity, uint64 price, uint64 quantityNotExecuted, enum LibOrderBookEvents.RejectionReasons reason, enum LibEnums.OrderKind side)
```

**Parameters**

| Name                | Type                                     | Description                    |
| ------------------- | ---------------------------------------- | ------------------------------ |
| client `indexed`    | address                                  | Client address                 |
| orderId `indexed`   | uint64                                   | unique order identifier        |
| quantity            | uint64                                   | Quantity of the order          |
| price               | uint64                                   | Limit price of the order       |
| quantityNotExecuted | uint64                                   | Quantity that was not executed |
| reason              | enum LibOrderBookEvents.RejectionReasons | Order rejection reason         |
| side                | enum LibEnums.OrderKind                  | Side of the order - buy / sell |

#### CancelOrder

```solidity
event CancelOrder(address indexed client, uint64 quantity, uint64 price, uint64 indexed orderId, enum LibLinkedList.CancellationType cancellationType, address tokenAddress, address toAddress)
```

Event emitted after order is canceled by participant or admin.

**Parameters**

| Name              | Type                                | Description                             |
| ----------------- | ----------------------------------- | --------------------------------------- |
| client `indexed`  | address                             | Client address                          |
| quantity          | uint64                              | Quantity of order                       |
| price             | uint64                              | Price of order                          |
| orderId `indexed` | uint64                              | OrderId of order added by order book    |
| cancellationType  | enum LibLinkedList.CancellationType | Type of cancellation                    |
| tokenAddress      | address                             | Token address                           |
| toAddress         | address                             | Address where collateral is transferred |

### OrderBook - Errors

#### OrderBook\_ExcludedForAdmin

```solidity
error OrderBook_ExcludedForAdmin()
```

* Error thrown when admin is trying to call function that is restricted to clients

#### OrderBook\_ForbiddenDueToMarketStatus

```solidity
error OrderBook_ForbiddenDueToMarketStatus(enum LibEnums.OrderBookPhases currentPhase)
```

* This error is thrown when an action is forbidden due to the current market status

**Parameters**

| Name         | Type                          | Description                                                                |
| ------------ | ----------------------------- | -------------------------------------------------------------------------- |
| currentPhase | enum LibEnums.OrderBookPhases | The current phase of the order book that caused the action to be forbidden |

#### OrderBook\_InvalidExecutionCondition

```solidity
error OrderBook_InvalidExecutionCondition(uint8 executionCondition)
```

* Error thrown when order execution condition is not valid

**Parameters**

| Name               | Type  | Description                  |
| ------------------ | ----- | ---------------------------- |
| executionCondition | uint8 | execution condition provided |

#### OrderBook\_InvalidInputOrderData

```solidity
error OrderBook_InvalidInputOrderData()
```

* Error thrown when order data is not valid - can't be parsed

#### OrderBook\_InvalidOrderKind

```solidity
error OrderBook_InvalidOrderKind(enum LibEnums.OrderKind orderKind)
```

* Error thrown when order kind is not valid

**Parameters**

| Name      | Type                    | Description              |
| --------- | ----------------------- | ------------------------ |
| orderKind | enum LibEnums.OrderKind | order kind (buy or sell) |

#### OrderBook\_InvalidOrderLifetime

```solidity
error OrderBook_InvalidOrderLifetime()
```

* Error thrown when lifetime parameter within order data for GoodTillDate/BookOrCancel is greater than 90

#### OrderBook\_InvalidOrderType

```solidity
error OrderBook_InvalidOrderType(uint8 orderType)
```

* Error thrown when order type is not valid

**Parameters**

| Name      | Type  | Description   |
| --------- | ----- | ------------- |
| orderType | uint8 | type or order |

#### OrderBook\_NotAllowedToBuy

```solidity
error OrderBook_NotAllowedToBuy()
```

* Error thrown when client is not allowed to buy

#### OrderBook\_NotAllowedToSell

```solidity
error OrderBook_NotAllowedToSell()
```

* Error thrown when client is not allowed to sell

#### OrderBook\_PreTradeControlOrderValueAboveMaxRange

```solidity
error OrderBook_PreTradeControlOrderValueAboveMaxRange()
```

* Error thrown when order value (orderQuantity \* orderPrice) is above max range

#### OrderBook\_PreTradeControlOrderValueBelowMinRange

```solidity
error OrderBook_PreTradeControlOrderValueBelowMinRange()
```

* Error thrown when order value (orderQuantity \* orderPrice) is below min range

#### OrderBook\_PreTradeControlOrderVolumeAboveMaxRange

```solidity
error OrderBook_PreTradeControlOrderVolumeAboveMaxRange()
```

* Error thrown when order volume (orderQuantity \* referencePrice) is above max range

#### OrderBook\_PreTradeControlOrderVolumeBelowMinRange

```solidity
error OrderBook_PreTradeControlOrderVolumeBelowMinRange()
```

* Error thrown when order volume (orderQuantity \* referencePrice) is below min range

#### OrderBook\_PreTradeControlPriceAboveMaxRange

```solidity
error OrderBook_PreTradeControlPriceAboveMaxRange()
```

* Error thrown when order price is above max range

#### OrderBook\_PreTradeControlPriceBelowMinRange

```solidity
error OrderBook_PreTradeControlPriceBelowMinRange()
```

* Error thrown when order price is below min range

#### OrderBook\_TickSize\_InvalidPrice

```solidity
error OrderBook_TickSize_InvalidPrice(uint256 price, uint256 tickSize)
```

* Error thrown when price can be divided by the tick size with rest

**Parameters**

| Name     | Type    | Description                 |
| -------- | ------- | --------------------------- |
| price    | uint256 | price provided              |
| tickSize | uint256 | ticksize for provided price |

#### ReentrancyShield\_ReentrantCall

```solidity
error ReentrancyShield_ReentrantCall()
```

* Error thrown on reentrant call

#### SafeERC20FailedOperation

```solidity
error SafeERC20FailedOperation(address token)
```

*An operation with an ERC-20 token failed.*

**Parameters**

| Name  | Type    | Description        |
| ----- | ------- | ------------------ |
| token | address | address of a token |

#### TransfersNotAccepted\_NativeCurrencyNotAccepted

```solidity
error TransfersNotAccepted_NativeCurrencyNotAccepted()
```

Error thrown when some native currency is sent to contract

#### AccessManaged\_Unauthorized

```solidity
error AccessManaged_Unauthorized(address caller)
```

* Error thrown when caller is not authorized.

**Parameters**

| Name   | Type    | Description                |
| ------ | ------- | -------------------------- |
| caller | address | address which caused error |

**Parameters**

| Name         | Type                          | Description                                                                |
| ------------ | ----------------------------- | -------------------------------------------------------------------------- |
| currentPhase | enum LibEnums.OrderBookPhases | The current phase of the order book that caused the action to be forbidden |

#### OrderBook\_InvalidClient

```solidity
error OrderBook_InvalidClient()
```

* Error thrown when client is not allowed to access order

#### OrderBook\_NoSuchOrderId

```solidity
error OrderBook_NoSuchOrderId(uint64 orderId)
```

* Error thrown when code is trying to access an order with id that not exists in the order book

**Parameters**

| Name    | Type   | Description               |
| ------- | ------ | ------------------------- |
| orderId | uint64 | provided order identifier |

#### OrderBook\_NotAllowedToCancel

```solidity
error OrderBook_NotAllowedToCancel()
```

* Error thrown when client is not allowed to cancel order
