-
Notifications
You must be signed in to change notification settings - Fork 91
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
Driver causes "GPv2: limit price not respected" on limit orders by rounding the price wrong #2457
Comments
The issue with rounding up would be that the user would potentially receive more tokens than the settlement contract would be able to generate from executing the solution leading to a potential loss for the protocol or solver. Solvers should compute prices in a way that takes this rounding behavior into account. |
OK got it thanks |
I'm having the exact same problem, but I disagree with the "solution". The smartcontract rounds up: https://github.com/cowprotocol/contracts/blob/main/src/contracts/GPv2Settlement.sol#L389-L391 So essentially we have a [Solver] <-> [Driver] <-> [Smartcontract] chain, where [Solver] is satisfying [Smartcontract] rules, but then there is a transformation in [Driver] that makes the solution invalid. My opinion is that any transformation between the solver and the smartcontract must preserve the fact if a solution is valid or not. There is a second problem with this transformation. The fact that the smartcontract is rounding up actually makes the task of rounding solutions to integers possible on the solver side. If it was rounding down, then we must solve a diophantine equation which does not seem trivial at all. So please, fix this. |
I figured out that the root cause of my problem was not the rounding down per se. My solving engine was submitting limit orders with 0 fee and the driver is adding a fee and modifying my clearing prices for these orders which turns my valid limit order solution into an invalid one. Ideally I'd like to be able to disable the entire driver logic of adding custom limit order prices and only use the price vector I provided instead. I'd save on gas and it wouldn't cause revert errors. |
Indeed, disabling the driver would solve it. But I would like to use the driver, and even if going forward the driver is managed by the solver, I'd prefer to patch it as least as possible. I have a lot of respect for the people that work on the driver, and don't think I can really make a better job there. In the smartcontract the exec_buy_amount (we are always talking about sell orders here) is computed as: exec_buy_amount = ceil(exec_sell_amount * price_sell_token / price_of_buy_token) [1] To me it makes sense the driver uses the same formula for any transformation it applies, at least when the transformation is advertised as "transparent" for the solver, which was the case for the protocol fee. |
Just to be clear, I was asking for a driver config flag to not add custom limit prices, not to bypass the driver entirely
Anyway, I agree with @marcovc that the driver shouldn't break a working solution and that it should use the same rounding method as the smart contract. |
Bypassing driver fees is captured by #2440. It should be straight forward so that issue could also be taken by an external contributor (see help-wanted tag). Let's keep this issue here focussed on the settlement encoder not rounding the same way as the smart contract. |
# Description See #2457 for the discussion. The settlement contract computes the buy amount for sell orders by rounding up the division of the uniform buy price (cf. https://github.com/cowprotocol/contracts/blob/main/src/contracts/GPv2Settlement.sol#L389-L391). The fact that the settlement encoder doesn't do this can lead to solutions getting rejected by the driver, which would be perfectly fine from the settlement contract's point of view. # Changes - [x] use `checked_ceil_div` instead of `checked div` ## How to test Existing unit tests (may need some updates, waiting for CI to tell me) ## Related Issues Fixes #2457
Description
Driver adds custom prices for limit orders in crates/solver/settlement_encoder.rs
it sets the sell token price as "buy amount" and the buy token price as "sell amount" in the settlement transaction.
However buy_amount is rounded down instead of up which causes the price limit to not be respected and the transaction simulation to fail.
the root cause is in line 351 of crates/solver/settlement_encoder.rs
** Solution**
Fix would be to implement something like this:
** Logs **
Driver logs:
2024-03-01T09:53:20.351Z INFO request{id="1"}:/solve{solver=MySolver auction_id=8531103}: driver::infra::observe: discarded solution: settlement encoding id=Id(0) err=Simulation(Revert(RevertError { err: Blockchain(Web3(Rpc(Error { code: ServerError(-32015), message: "Reverted 0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001f475076323a206c696d6974207072696365206e6f742072657370656374656400",
My solver passed a solution with the following clearing prices for order "0xfdade0ee290adcab31f2323190d3bc7e9b12e0f5c3d6b599334fc8dfb6375aa8844dc85edd8492a56228d293cfebb823ef3e10ec66050708":
and the driver set the buy_amount to buy_amount= 34558023172 , but
sell_amount * uniform_sell_price / uniform_buy_price = 34558023172.5,
the buy_amount should be 34558023173
The text was updated successfully, but these errors were encountered: