marigold-dev / batcher

The aim of the batch clearing dex is to enable users to deposit tokens with the aim of being swapped at a fair price with bounded slippage and almost no impermanent loss.
https://batcher.marigold.dev/
MIT License
10 stars 2 forks source link

Order matching #1

Closed glottologist closed 2 years ago

glottologist commented 2 years ago
Hakimba commented 2 years ago

I'll take this one

Hakimba commented 2 years ago

I just push some little code into this branch : https://github.com/marigold-dev/0-slip/tree/hakb%40order_matching that i will extend as my understanding of the subject evolves.

So, from my understanding, if i had to draw a overview of the project, that will be like :

(I will explain from a "differents smart contracts" POV, its easier for me to think like this but of course at the end we will have only one contract as you said earlier)

  1. the user ask for a swap, that call the treasury contract on the Deposit entrypoint
  2. The treasury contract create an order with the asked token, the amount, he create a expiry on the fly (would be like Tezos.now + N ?) and he call the Ordering entrypoint of the _ordermatch contract with the freshly created order.
  3. The _ordermatch contract push the given order into his storage (for now, for keeping this simple as possible, its just two list)
  4. We can continue to push orders or we can call the Tick entrypoint of the _ordermatch contract for triggering the match/remove orders phase
  5. No matter what is the result of a match/remove orders phase, we will call the Redeem entrypoint of the treasury contract in order to giving back the right amount of asset to the user.

Did i understood something wrong or forgot something ? I'm looking forward your thoughts and suggestions about this and the code as well.

glottologist commented 2 years ago

Yep sounds correct. Just one point:

  1. Only those orders that have been filled (either complete or partial) or expired will need to redeem the tokens
Hakimba commented 2 years ago

I have questions regarding the match algorithm.

im not sure to understand when there is a match. Are we agree that we can have an order book with bids and asks with arbitrary prices ? So there is a match when a bid and an ask have the exact same price ?

Or there is a match when I found a seller order with a price <= to the buyer order ? (Vice versa for the opposite case >=)

glottologist commented 2 years ago

"You can also incentivize market makers by saying that you're willing to trade .2% over/under the market price"

So there needs to be a spread for the market making. So if the seller order is found within the price+spread it should be matched. For the moment, lets work on the assumption that it is "upto" a .2% (2bps) spread - we can adjust the rules around this later.

Hakimba commented 2 years ago

I add an naive algorithm for the orders matching (and modified the pushOrder in order to keep a sorted (by the price) orders list).

For now i didn't use a spread so i check a strict equality between price, the algo is like :

i have a list of bid and ask [B1;A1;B2;A2;B3;A3] for example, i'll check for each couple (so B1A1, A1B2 etc..), if a couple is compatible (different order type, a bid and an ask) and if the price is exactly the same, i compute the match with match_compute which return a Total or a Partial of order (look at the interface for the types), and i do that until the end of the list.

So for example, if i have

let order1 = {
  trader = "alice";
  userType = B;
  amount = 7;
  price = 1
}
let order2 = {
  trader = "thomas";
  userType = S;
  amount = 5;
  price = 4
}
let order3 = {
  trader = "bob";
  userType = B;
  amount = 9;
  price = 1
}
let order4 = {
  trader = "xavier";
  userType = S;
  amount = 5;
  price = 1
}

My orders list will be

[{trader = "alice"; userType = B; amount = 7; price = 1};
   {trader = "bob"; userType = B; amount = 9; price = 1};
   {trader = "xavier"; userType = S; amount = 5; price = 1};
   {trader = "thomas"; userType = S; amount = 5; price = 4}]

And if i call match_orders on this list i have

[{trader = "alice"; userType = B; amount = 7; price = 1};
 {trader = "bob"; userType = B; amount = 4; price = 1};
 {trader = "thomas"; userType = S; amount = 5; price = 4}]

Because I can reduce bob and xavier and bob have 4 amount left after buying the 5 amount en S to xavier. I'll add tests for those kind of scenario, The algo is inefficient of course but can you tell me if i understood well the matching thing or/and if there is errors i missed ? Thanks.

kienle371999 commented 2 years ago

Hi @Hakimba Whenever you find a compatible token pair (entirely or partially matching), you can choose this and terminate the loop. It is more efficient than trying out all of the items. You can consider this matching which is over/under .2% the market price is acceptable.

Hakimba commented 2 years ago

Hi @Hakimba Whenever you find a compatible token pair (entirely or partially matching), you can choose this and terminate the loop. It is more efficient than trying out all of the items. You can consider this matching which is over/under .2% the market price is acceptable.

Hi Kien, thanks for your review, however i'm not sure i understand your advice, my naive algorithm aims to match orders as much as possible, thats why i go through the entire list, maybe i misunderstodd the concept of the order book and the matching ? But from my understanding, we want to match all the orders pair we can during the process.

Don't hesitate to tell me if i'm wrong (on the PR instead of here, i guess its better)