Skip to content

Commit

Permalink
In-market classification for fill-or-kill limit orders (#335)
Browse files Browse the repository at this point in the history
This PR implements the same change as this
PR(cowprotocol/dune-sync#73) for dune-sync.
Tests have been adapted to the new query. It should be live in
production before the payment on 2024-02-06.

Text from there:

We currently classify limit orders as in-market based on quoted amounts,
see [dune sync #61](cowprotocol/dune-sync#61).
As it turns out, those amounts do not take fees into account for limit
orders. Therefore we misclassify some orders whicch are out-of-market as
in-market.

This PR changes the classification of in-market orders to be in line
with how market orders are created in the frontend: If the quoted
amounts are `oq.sell_amount` and `oq.buy_amount` and the estimated fee
is `oq.gas_amount * oq.gas_price / oq.sell_price` then a market order
sell order would have charged a fee of `oq.gas_amount * oq.gas_price /
oq.sell_price` and exchanged the remaining abount `oq.sell_amount -
oq.gas_amount * oq.gas_price / oq.sell_price` at the quoted exchange
rate `oq.buy_amount / oq.sell_amount` to a buy amount of
`(oq.sell_amount - oq.gas_amount * oq.gas_price / oq.sell_price) /
oq.sell_amount * oq.buy_amount`. Thus an order would be in-market if
`o.buy_amount <= (oq.sell_amount - oq.gas_amount * oq.gas_price /
oq.sell_price) / oq.sell_amount * oq.buy_amount`, whoch is equivalent to
`(oq.sell_amount - oq.gas_amount * oq.gas_price / oq.sell_token_price) *
oq.buy_amount >= o.buy_amount * oq.sell_amount`.

For a buy order a reasonable market order would have traded
`oq.sell_amount + oq.gas_amount * oq.gas_price / oq.sell_token_price` to
`oq.buy_amount`. Thus an order is regarded as in-market if
`o.sell_amount >= oq.sell_amount + oq.gas_amount * oq.gas_price /
oq.sell_token_price`.

These rules are implemented in this PR.

Note that those rules are not really applicable to paartially-fillable
orders. It can happen that an execution for the full amount is not
possible (out-of-market) but smaller chunks can be executed. When that
usecase arises we need to revisit this code.
  • Loading branch information
fhenneke authored Feb 5, 2024
1 parent 2bda2b1 commit fa54e13
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 18 deletions.
7 changes: 4 additions & 3 deletions queries/orderbook/quote_rewards.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ with winning_quotes as (SELECT concat('0x', encode(oq.solver, 'hex')) as solver,
FROM trades t
INNER JOIN orders o ON order_uid = uid
JOIN order_quotes oq ON t.order_uid = oq.order_uid
WHERE ((o.kind = 'sell' AND o.buy_amount <= oq.buy_amount)
OR (o.kind='buy' AND o.sell_amount >= oq.sell_amount))
AND o.partially_fillable='f'
WHERE (o.class = 'market'
OR (o.kind = 'sell' AND (oq.sell_amount - oq.gas_amount * oq.gas_price / oq.sell_token_price) * oq.buy_amount >= o.buy_amount * oq.sell_amount)
OR (o.kind='buy' AND o.sell_amount >= oq.sell_amount + oq.gas_amount * oq.gas_price / oq.sell_token_price))
AND o.partially_fillable='f' -- the code above might fail for partially fillable orders
AND block_number >= {{start_block}} AND block_number <= {{end_block}}
AND oq.solver != '\x0000000000000000000000000000000000000000')

Expand Down
36 changes: 21 additions & 15 deletions tests/queries/quote_rewards_test_db.sql
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
DROP TABLE IF EXISTS orders;
DROP TYPE IF EXISTS OrderKind;
DROP TYPE IF EXISTS OrderClass;
DROP TABLE IF EXISTS order_quotes;
DROP TABLE IF EXISTS trades;


-- orders table
CREATE TYPE OrderKind AS ENUM ('buy', 'sell');
CREATE TYPE OrderClass AS ENUM ('market', 'limit');

CREATE TABLE IF NOT EXISTS orders
(
Expand All @@ -14,12 +16,16 @@ CREATE TABLE IF NOT EXISTS orders
buy_amount numeric(78,0) NOT NULL,
fee_amount numeric(78,0) NOT NULL,
kind OrderKind NOT NULL,
partially_fillable boolean NOT NULL
partially_fillable boolean NOT NULL,
class OrderClass NOT NULL
);

CREATE TABLE IF NOT EXISTS order_quotes
(
order_uid bytea PRIMARY KEY,
gas_amount numeric(78, 0) NOT NULL,
gas_price numeric(78, 0) NOT NULL,
sell_token_price float NOT NULL,
sell_amount numeric(78, 0) NOT NULL,
buy_amount numeric(78, 0) NOT NULL,
solver bytea NOT NULL
Expand All @@ -42,21 +48,21 @@ TRUNCATE order_quotes;
TRUNCATE trades;


INSERT INTO orders (uid, sell_amount, buy_amount, fee_amount, kind, partially_fillable)
VALUES ('\x01'::bytea, 95000000, 94000000000000000000, 5000000, 'sell', 'f'), -- normal sell market order
('\x02'::bytea, 101000000, 100000000000000000000, 5000000, 'buy', 'f'), -- normal buy market order
('\x03'::bytea, 100000000, 100000000000000000000, 0, 'sell', 't'), -- partially fillable sell limit order
('\x04'::bytea, 100000000, 100000000000000000000, 0, 'buy', 't'), -- partially fillable buy limit order
('\x05'::bytea, 100000000, 94000000000000000000, 0, 'sell', 'f'), -- in market sell limit order
('\x06'::bytea, 106000000, 100000000000000000000, 0, 'buy', 'f'); -- in market buy limit order
INSERT INTO orders (uid, sell_amount, buy_amount, fee_amount, kind, partially_fillable, class)
VALUES ('\x01'::bytea, 95000000, 94000000000000000000, 5000000, 'sell', 'f', 'market'), -- normal sell market order
('\x02'::bytea, 101000000, 100000000000000000000, 5000000, 'buy', 'f', 'market'), -- normal buy market order
('\x03'::bytea, 100000000, 100000000000000000000, 0, 'sell', 't', 'limit'), -- partially fillable sell limit order
('\x04'::bytea, 100000000, 100000000000000000000, 0, 'buy', 't', 'limit'), -- partially fillable buy limit order
('\x05'::bytea, 100000000, 94000000000000000000, 0, 'sell', 'f', 'limit'), -- in market sell limit order
('\x06'::bytea, 106000000, 100000000000000000000, 0, 'buy', 'f', 'limit'); -- in market buy limit order

INSERT INTO order_quotes (order_uid, sell_amount, buy_amount, solver)
VALUES ('\x01'::bytea, 95000000, 95000000000000000000, '\x01'::bytea),
('\x02'::bytea, 101000000, 100000000000000000000, '\x02'::bytea),
('\x03'::bytea, 100000000, 95000000000000000000, '\x03'::bytea),
('\x04'::bytea, 105000000, 100000000000000000000, '\x03'::bytea),
('\x05'::bytea, 100000000, 95000000000000000000, '\x03'::bytea),
('\x06'::bytea, 105000000, 100000000000000000000, '\x03'::bytea);
INSERT INTO order_quotes (order_uid, gas_amount, gas_price, sell_token_price, sell_amount, buy_amount, solver)
VALUES ('\x01'::bytea, 100000, 25000000000, 500000000., 95000000, 95000000000000000000, '\x01'::bytea),
('\x02'::bytea, 100000, 25000000000, 500000000., 100000000, 100000000000000000000, '\x02'::bytea),
('\x03'::bytea, 100000, 25000000000, 500000000., 100000000, 100000000000000000000, '\x03'::bytea),
('\x04'::bytea, 100000, 25000000000, 500000000., 100000000, 100000000000000000000, '\x03'::bytea),
('\x05'::bytea, 100000, 25000000000, 500000000., 100000000, 100000000000000000000, '\x03'::bytea),
('\x06'::bytea, 100000, 25000000000, 500000000., 100000000, 100000000000000000000, '\x03'::bytea);

INSERT INTO trades (block_number, log_index, order_uid, sell_amount, buy_amount)
VALUES (1, 0, '\x01'::bytea, 100000000, 95000000000000000000),
Expand Down

0 comments on commit fa54e13

Please sign in to comment.