Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revise Offer lists page #219

Merged
merged 2 commits into from
Jan 17, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,97 +5,88 @@ sidebar_position: 2

# Offer Lists

## General structure
An "offer list" corresponds to either the "asks" or "bids" side of an order book. Mangrove has no explicit on-chain representation of an order book, only offer lists.

:::danger There are 2 offer lists per market
An "offer list" corresponds to either the "asks" or "bids" side of an order book. Mangrove being fully on-chain, there is no actual concept of an order book, only offer lists.
Hence, a full market will always feature **two offer lists**. For instance, a WETH/DAI market consists of:

Hence, a full market will always feature **two offer lists**. For instance, a WETH/DAI market has:
* The DAI-WETH offer list (where DAI is offered in exchange for WETH)
* The WETH-DAI offer list (where WETH is offered in exchange for DAI)
* a WETH-DAI offer list (where WETH is offered in exchange for DAI)
* a DAI-WETH offer list (where DAI is offered in exchange for WETH)

[Mangrove's SDK ](../../../SDK/README.md) offers Market abstractions that allows liquidity providers and takers to interact with Mangrove using standard trading _base_ and _quote_ denominations.
:::info market abstractions over offer lists
[Mangrove's SDK](../../../SDK/README.md) offers Market abstractions that allows liquidity providers and takers to interact with Mangrove using standard trading concepts such as _order book_, _base_, and _quote_.
:::

### Dealing with offer lists
An offer list is identified by a tuple of (`outbound_tkn`, `inbound_tkn`, `tickSpacing`). For example, for a WETH-DAI offer list, the touple values would be:

For more information on ticks, head over the [previous section](../tick-ratio.md).
* `outbound_tkn`: the address of the WETH token (i.e., sent by the offer)
* `inbound_tkn`: the address of the DAI token (i.e., wanted by the offer)
* `tickSpacing`: typically 1 meaning that all ticks are allowed (see the [previous page](../tick-ratio.md) for details).

1. An offer list is identified by a tuple of (`outbound_tkn`, `inbound_tkn`, `tickSpacing`). For example in a WETH-DAI offer list:
* `outbound_tkn` is the address of the WETH token (i.e., sent by the offer)
* `inbound_tkn` is the address of the DAI token (i.e., wanted by the offer)
* `tickSpacing` corresponds to the space between [bins](#bins-doubly-linked-lists)

2. Offers are grouped by tick into "[tick bins](../tick-ratio.md#3-tick-bins)" - one bin per valid tick. Within a tick bin, the offers are stored in a FIFO doubly linked-list (an offer points to the previous **and** to the next one).
Offers are grouped by tick. The offers for a given tick are stored in a FIFO, doubly linked-list (an offer points to the previous **and** to the next one).

import useBaseUrl from '@docusaurus/useBaseUrl';

<div class="text--center">
<img src={useBaseUrl('/img/assets/bin.png')} width="60%"/>
</div>

3. Posting and updating offers are done with constant gas thanks to tick bins being organized internally in a [tree structure](../tick-ratio.md#2-tick-tree).


### Example

We will repeat ourselves a bit here, but grasping the concept of offer lists is very important for you to interact with Mangrove. Let's take our WETH/DAI market, and look at its two corresponding offer lists:
* DAI-WETH
* WETH-DAI

:::caution Note
If you haven't done it yet, we strongly suggest that you first get familiar with the [Ticks and ratio](../tick-ratio.md#price--wants) page.
If you haven't done it yet, we strongly suggest that you first get familiar with the [Ticks, ratios, and prices](../tick-ratio.md) page.
:::

#### Offer list #1 - DAI-WETH
## Example: WETH/DAI market

In this DAI-WETH offer list:
* WETH is the base token
* DAI the quote token (giving DAI to buy WETH)
* Thus, since the ratio is in WETH/DAI, **the price is the `ratio`**
Let's take a WETH/DAI market and look at its two corresponding offer lists, WETH-DAI and DAI-WETH, with `tickSpacing = 1`:

We can illustrate this with the following sample DAI-WETH offer list with three offers. Only the main characteristics of the offers are shown (see the [offer data structure](reactive-offer/offer-data-structures.md#mgvlib-offer)).
### Offer list #1: WETH-DAI ("asks")

For a WETH/DAI market, the WETH-DAI offer list corresponds to the "asks" of the order book:

| Tick | Ratio (WETH/DAI) | Offer ID | Gives (DAI) | Gas required | Maker Contract | Offer Gas Price |
| ------- | ---------------- | -------- | ----------- | ------------ | -------------- | --------------- |
| -79815 | 0.0003419 | 77 | 925.26 | 250,000 | 0x5678def | 150 |
| | | 177 | 916.47 | 270,000 | 0x9101ghi | 170 |
| -79748 | 0.0003442 | 42 | 871.76 | 300,000 | 0x1234abc | 200 |
* WETH is the _outbound_ token, i.e, offers give WETH
* DAI is the _inbound_ token, i.e, offers want DAI
* The unit of %%ratios|ratio%% is DAI/WETH and price = ratio.

Here's an example of such an offer list:

##### Understanding the table
* **Tick**: a number derived from the ratio (price), pointing to a [tick bin](../tick-ratio.md#3-tick-bins). All offers in a bin have the same tick.
* **Ratio**: tells us how much WETH (base) we get per DAI (quote).
* **Offer ID**: more information [below](#offer-id).
* **Gives**: more information on the [Ticks and ratio](../tick-ratio.md#price--wants) page.
* **Gas required**: the amount of gas needed to cover all calls to the maker contract's [offer logic](./reactive-offer/maker-contract.md).
* **Maker contract**: the address of the [maker contract](./reactive-offer/README.md) (smart offer).
* **Offer gas price**: gas price override used to compute the order's %%provision|provision%% (see also [offer bounties](../taking-and-making-offers/reactive-offer/offer-provision.md#bounty-calculation)).
| Tick | Ratio (DAI/WETH) | Offer ID | Gives (WETH) | Gas required | Maker Contract | Offer Gas Price |
| ------- | ---------------- | -------- | ----------- | ------------ | -------------- | --------------- |
| 75171 | 1838.53 | 42 | 0.7 | 220,000 | `0x2468xyz...` | 160 |
| | | 96 | 1.3 | 280,000 | `0x1357klm...` | 140 |
| 75200 | 1843.87 | 7 | 0.6 | 210,000 | `0x3287opq...` | 190 |

#### Understanding the table

#### Offer list #2 - WETH-DAI
* **Tick**: The discrete "price" %%tick|tick%% of the offer which corresponds to a ratio and price. Offers at the same tick are stored in FIFO order and in the table we only show the tick and ratio for the first offer with that tick.
espendk marked this conversation as resolved.
Show resolved Hide resolved
* **Ratio**: The amount of inbound token to be paid per outbound token. This is not stored on-chain, but is derived from the tick.
* **Offer ID**: An ID for the offer which is assigned by Mangrove when the offer is first created. The ID is unique only on that offer list.
* **Gives**: The amount of outbound token offered.
* **Gas required**: The amount of gas needed to execute the offer and its posthook.
* **Maker contract**: The address of the make who posted the offer. Either an EOA or a [maker contract](./reactive-offer/README.md) (for smart offers).
* **Offer gas price**: Gas price used to compute the order's %%provision|provision%% (see also [offer bounties](../taking-and-making-offers/reactive-offer/offer-provision.md#bounty-calculation)). Must be at least Mangrove's gas price when the offer is posted.

This is the mirrored offer list, where:
* DAI is the base token
* WETH the quote token (giving WETH to buy DAI)
* Thus, since the ratio is in WETH/DAI (WETH per DAI), **the price in this offer list is `ratio^(-1)` (DAI per WETH)**
:::caution Beware Decimals
We display human-readable amounts in the examples for readability, but on-chain Mangrove only works with raw token values and never uses the `decimals` a token.

For simplicity, the tokens used in these examples have the same number of decimals (18). When that's not the case, care must be taken to handle decimals, especially for ratios.

[TO RECALCULATE TICKS WITH DIFFERENT RATIO?]
See the [Ticks, ratios, and prices](../tick-ratio.md) page for a detailed discussion of decimals.
:::

| Tick | Ratio (WETH/DAI) | Offer ID | Gives (WETH) | Gas required | Maker Contract | Offer Gas Price |
| ------- | ---------------- | -------- | ----------- | ------------ | -------------- | --------------- |
| -79815 | 0.0003419 | 13 | 0.7 | 220,000 | 0x2468xyz | 160 |
| | | 96 | 1.3 | 280,000 | 0x1357klm | 140 |
| -79748 | 0.0003442 | 7 | 0.6 | 210,000 | 0x3287opq | 190 |
### Offer list #2: DAI-WETH ("bids")

For a WETH/DAI market, the DAI-WETH offer list corresponds to the "bids" of the order book:

:::caution **Decimals**
We display human-readable values in the examples, but Mangrove stores raw token values and never uses the `decimals` field of a token.
:::
* DAI is the _outbound_ token, i.e, offers give DAI
* WETH is the _inbound_ token, i.e, offers want WETH
* The unit of %%ratios|ratio%% is WETH/DAI and price = ratio$^{-1}$.

Here's an example of such an offer list:

| Tick | Ratio (WETH/DAI) | Offer ID | Gives (DAI) | Gas required | Maker Contract | Offer Gas Price |
| ------- | ---------------- | -------- | ----------- | ------------ | -------------- | --------------- |
| -75103 | 0.0005476 | 77 | 925.26 | 250,000 | `0x5678def...` | 150 |
| | | 177 | 916.47 | 270,000 | `0x9101ghi...` | 170 |
| -75041 | 0.0005510 | 42 | 871.76 | 300,000 | `0x1234abc...` | 200 |

## Some terminology

Expand All @@ -104,18 +95,15 @@ We display human-readable values in the examples, but Mangrove stores raw token
The identifier of the offer in the offer list.

:::danger **Important**
Two offers may have the same ID as long as they belong to different offer lists. For instance, there may be an offer with ID 42 on the WETH-DAI offer list with different volumes, gas required, maker contract, etc., than the offer with ID 42 in the DAI-WETH offer list shown above.
Two offers may have the same ID as long as they belong to different offer lists. For instance, in the example above, both offer lists contain offers with ID 42.
:::


### Gas required

The maximum amount of gas the %%maker contract|maker-contract%% managing the offer will be allowed to spend if called by Mangrove.
The maximum amount of gas the %%maker contract|maker-contract%% managing the offer will be allowed to spend if called by Mangrove. This includes both `makerExecute` and `makerPosthook`.

:::info **Example**

The offer with ID 77 may consume up to 250K gas units.

The offer with ID 77 in the DAI-WETH offer list above may consume up to 250K gas units.
:::

### Maker Contract
Expand All @@ -128,6 +116,12 @@ An offer _may_ also be posted from EOA with no logic attached - see %%On-the-fly

Gas price that was used to compute the %%offer provision|provision%%. If the offer fails to deliver the promised **outbound tokens**, it will be charged based on this gasprice.

The gas price of an offer must be at least Mangrove's gas price at the time when the offer is posted.

## Offer list configuration

Several [configuration](../governance-parameters/mangrove-configuration.md) parameters determine how new offers are inserted. Some are [global](../governance-parameters/global-variables.md) to Mangrove, some are [offer list specific.](../governance-parameters/local-variables.md) See [Governance](../governance-parameters/README.md) section for details.

## Gas cost of posting, updating, and retracting offers

The gas cost for posting, updating, and retracting offers is bounded by a constant thanks to ticks being organized internally in a fixed tree structure. The details are described in the [annotated code](pathname:///MgvDoc/) of the Mangrove protocol.