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

Price improvement tests #2467

Closed
wants to merge 14 commits into from
Closed

Price improvement tests #2467

wants to merge 14 commits into from

Conversation

squadgazzz
Copy link
Contributor

@squadgazzz squadgazzz commented Mar 4, 2024

Description

Fixes #2479

@squadgazzz squadgazzz force-pushed the 2287/price-improvement-tests branch from 5042984 to 666f4fe Compare March 5, 2024 09:34
@squadgazzz squadgazzz force-pushed the 2287/price-improvement-tests branch 2 times, most recently from e103df2 to dd233e2 Compare March 5, 2024 11:08
@squadgazzz squadgazzz marked this pull request as ready for review March 5, 2024 11:43
@squadgazzz squadgazzz requested a review from a team as a code owner March 5, 2024 11:43
@squadgazzz
Copy link
Contributor Author

squadgazzz commented Mar 5, 2024

Still not quite sure this PR should replace all of the unit tests

crates/driver/src/tests/cases/protocol_fees.rs Outdated Show resolved Hide resolved
crates/driver/src/tests/cases/protocol_fees.rs Outdated Show resolved Hide resolved
Comment on lines 212 to 214
quote_sell_amount: quote_sell_amount.into(),
quote_buy_amount: quote_buy_amount.into(),
executed: quote_buy_amount.into(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can we charge any fee here? The quote amount is equal to the executed amount so there is no price improvement. Doesn't this test framework now need a way of differentiating between the quoted and executed price? Also, are we even using an executed amount that is lower than the full amount in any test case (ie are we testing partial fills somewhere)

Overall, I still find these test cases a bit hard to parse (imagine someone trying to debug a failing test case and trying to reproduce the assumptions and math that is going on here).

I don't think we necessarily have to find the nicest abstraction that leads to the least code (e.g. I think we could have a different TestCase setup for price improvement fee vs. surplus fee if one is structurally more complex), but let's please make those tests easier to comprehend.

Copy link
Contributor Author

@squadgazzz squadgazzz Mar 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before refactoring, now I understand that I am confused about a condition when an order is inside or outside market price.
Can out of market orders be defined as (order.sell + order.fee) * quote.buy < (quote.sell + quote.fee) * order.buy?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe so, yes (looking at @sunce86 to confirm)

order_side: order::Side::Sell,
fee_policy,
order_sell_amount: order_sell_amount.into(),
solver_fee: Some(10000000000000000000u128.into()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I think it would be clearer to call this network_fee in this context.

I do see now that the price improvement comes from the network fee being different than the quoted fee. This is very clever but not something I'd expect someone maintaining this code in 3 month to just guess without context, so please let's help your future colleague to understand how this test work more intuitively.

};

protocol_fee_test_case(test_case).await;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partially fillable orders are missing.

Also can we add a test that shows shifting surplus into network fees doesn't change the protocol fee charged? E.g. the following two executions pay the same fee (assuming same underlying orders & quotes)

  1. Sell 0.1 ETH receive 3500 DAI, pay 0.9 ETH in network fees
  2. Sell 1 ETH receive 3500 DAI, pay 0 in network fees

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Partially fillable orders require some further refactoring. I will create a separate issue for this.

crates/driver/src/tests/setup/mod.rs Outdated Show resolved Hide resolved
@squadgazzz squadgazzz force-pushed the 2287/price-improvement-tests branch from 4c68e5c to 4d4ad2f Compare March 5, 2024 19:57
@squadgazzz squadgazzz force-pushed the 2287/price-improvement-tests branch from 4d4ad2f to 38135e8 Compare March 5, 2024 20:45
@squadgazzz squadgazzz force-pushed the 2287/price-improvement-tests branch from 2a20508 to 287c1f9 Compare March 5, 2024 20:59
Copy link
Contributor

@fleupold fleupold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we capture the follow up item of adding tests for partial fills (I believe this might also be missing for the surplus fee policy)?

nvm #2480

order_side: order::Side::Buy,
fee_policy,
order_sell_amount,
network_fee: Some(2000000000000000000u128.into()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will likely be easier to see with #2472, but can you comment in code how the price improvement is achieved (realized network fee lower than quote, leading to X price improvement). This will help understand the expected executed sell amount (compared to the quoted one), but maybe you can add a comment for this expectation as well.

Should be done for each test.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Started writing the comments and found out that the results look pretty weird. Found this code which applies a default surplus factor. Not sure if it needs to be eliminated for the price improvement tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, either we need to set it in the test case or make sure it's set to 1. I think your trick with reducing the fee is good enough and allows us to more precisely reason about absolute surplus values (rather than a factor), so I'd slightly prefer setting the factor to 1 (but no strong feelings, as longs as it's clear from the main test how the calculation is carried out)

@squadgazzz squadgazzz marked this pull request as draft March 6, 2024 17:05
@squadgazzz squadgazzz force-pushed the 2287/price-improvement-tests branch from 2390320 to 3a80fe6 Compare March 7, 2024 18:59
# Conflicts:
#	crates/driver/src/tests/cases/protocol_fees.rs
#	crates/driver/src/tests/setup/blockchain.rs
@squadgazzz squadgazzz marked this pull request as ready for review March 8, 2024 18:25
} => quote.network_fee,
_ => eth::U256::zero(),
};
(self.buy * (self.sell - fee) / self.sell) / self.order.surplus_factor
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it valid?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should always incorporate some network fee here (and not have an if branch just for PriceImprovement fees. That feels way too hacky.

} => quote.network_fee,
_ => eth::U256::zero(),
};
(self.sell + fee) * self.order.surplus_factor
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it valid?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

Copy link
Contributor

@fleupold fleupold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still find the whole setup very hacky and cannot see myself maintaining these tests.

Can we limit our price improvement for now to be only based on the difference in estimted network fee and actually network fee?

Then, a test case just needs a quote (which determines the order amounts and the expected fee), an actual fee amount (which determines the price improvement), a side and the expected amounts.

We shouldn't create if branches deep inside the test setup to cater to one specific test case but instead rethink the setup to make it work with all fee models.

Comment on lines +82 to +83
.sell_amount(test_case.order_sell_amount)
.buy_amount(test_case.order_buy_amount);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is that set from the order amounts and not from the quote?

quote,
order_sell_amount,
order_buy_amount,
network_fee: Some(1.ether().into_wei()),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are still not saying anywhere that this is the little detail that leads to price improvement. This is way to hidden to leave this uncommented.

network_fee: Some(network_fee),
executed: order_sell_amount - network_fee,
executed_sell_amount: order_sell_amount,
// todo: how to prove the value?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well how is it calculated? Comment with the math that leads to this value.

Let's maybe start by "where is the price improvement coming from in this test"? I see sell amount and buy amounts and network fees are equal for quote and orders. Unclear why there is any price improvement fee here?

} => quote.network_fee,
_ => eth::U256::zero(),
};
(self.buy * (self.sell - fee) / self.sell) / self.order.surplus_factor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should always incorporate some network fee here (and not have an if branch just for PriceImprovement fees. That feels way too hacky.

} => quote.network_fee,
_ => eth::U256::zero(),
};
(self.sell + fee) * self.order.surplus_factor
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

@fleupold
Copy link
Contributor

fleupold commented Mar 9, 2024

Can we limit our price improvement for now to be only based on the difference in estimated network fee and actually network fee?

Actually maybe this wasn't a good idea to begin with (assuming it's the reason for the conditional refactoring). In this case, you can also work with explicit order and quote amounts and just assume 0 network everywhere.

@fleupold fleupold mentioned this pull request Mar 10, 2024
5 tasks
@fleupold
Copy link
Contributor

@squadgazzz I created #2510 as a suggestion on how I would implement these tests. Can you take a look, tell me what you think about this approach and if it works and if convert the remaining tests?

@squadgazzz
Copy link
Contributor Author

#2510

@squadgazzz squadgazzz closed this Mar 11, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Mar 11, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement Price Improvement integration tests
3 participants