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

fix: estimated execution price #5308

Merged
merged 17 commits into from
Jan 23, 2025
Merged

Conversation

alfetopito
Copy link
Collaborator

@alfetopito alfetopito commented Jan 17, 2025

Summary

Overhaul estimated fill price in the form (and a bit in the table)

  • Unified calculation in the single method

Overloaded getEstimatedExecutionPrice to be used in the ExecutionPriceUpdater
It now can also take order parameters without having an existing order

  • Taking into account order flag partially fillable

Now it'll use a fixed sell amount to make estimation stable regardless of order size
The amount is currently set to 50x 1000x feeAmount
From there, we use the chosen limit price (already discounted for potential fees) to derive the buy amount
Lastly, the feeAmount is deduced from the calculated sell amount, to give us the new estimated price

If the order is fill or kill OR the amount calculated above is bigger than actual sell amount, use the old way considering the whole sell amount

  • Adding the fee to market price as well

One last adjustment, is to use the same method above to add the fee to the market price as well
We know we cannot execute exactly at the spot price because we need to take fees into account
So the same 50x 1000x the fee strategy is applied to the spot price in case the limit price is below market.

To Test

  1. Play around with limit orders fill or kill and partially fillable
  2. Verify the values on the open orders table
  3. If the order is partially fillable, higher amounts shouldn't impact estimated fill price (when amount > 50x fee)

TODO

  • update unit tests
  • add unit tests for overloaded variation

Copy link

vercel bot commented Jan 17, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
cowfi 🔄 Building (Inspect) Visit Preview Jan 23, 2025 11:41am
explorer-dev ✅ Ready (Inspect) Visit Preview Jan 23, 2025 11:41am
sdk-tools 🔄 Building (Inspect) Visit Preview Jan 23, 2025 11:41am
swap-dev ✅ Ready (Inspect) Visit Preview Jan 23, 2025 11:41am
2 Skipped Deployments
Name Status Preview Updated (UTC)
cosmos ⬜️ Ignored (Inspect) Visit Preview Jan 23, 2025 11:41am
widget-configurator ⬜️ Ignored (Inspect) Visit Preview Jan 23, 2025 11:41am

@alfetopito alfetopito changed the base branch from develop to fix/distance-to-market January 17, 2025 17:27
Base automatically changed from fix/distance-to-market to feat/limit-ui-upgrade-2 January 20, 2025 11:20
Base automatically changed from feat/limit-ui-upgrade-2 to feat/limit-ui-upgrade January 20, 2025 15:21
@alfetopito alfetopito marked this pull request as ready for review January 20, 2025 15:52
@alfetopito alfetopito self-assigned this Jan 20, 2025
let sellAmount: string
let partiallyFillable = isPartiallyFillable

if (order) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here we handle the case when the order exists

// Check what's left to sell, discounting the surplus, if any
sellAmount = getRemainderAmountsWithoutSurplus(order).sellAmount
partiallyFillable = order.partiallyFillable
} else {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here is the case when we have the order parameters only

return new Price(order.inputToken, order.outputToken, '0', '0')
let feasibleExecutionPrice: Price<Currency, Currency> | undefined = undefined

if (partiallyFillable) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here we apply the fee multiplier strategy for a fixed estimated fill price

Comment on lines +332 to +352
// Regular case, when the order is fill or kill OR the fill amount is smaller than the threshold set
if (feasibleExecutionPrice === undefined) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here's the case for fill or kills, or small partial fill amounts

*/
feasibleExecutionPrice = new Price(inputToken, outputToken, denominator.quotient, numerator.quotient)

console.log(`getEstimatedExecutionPrice: fill or kill`, {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

TODO: remove logs before merging

Comment on lines 361 to 370
// // Make the fill price a bit worse to account for the fee
const newFillPrice =
extrapolatePriceBasedOnFeeAmount(feeAmount, remainingSellAmount, fillPrice, inputToken, outputToken) || fillPrice
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

And here we make the fill price slightly worse to account for the fee

newSellAmount.subtract(feeAmount).quotient, // TODO: should we use the fee with margin here?
buyAmount.quotient,
)
console.log(`getEstimatedExecutionPrice: partially fillable`, {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

TODO: remove before merging

Comment on lines +41 to +43
useSafeEffect(() => {
updateLimitRateState({ feeAmount })
}, [feeAmount, updateLimitRateState])
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We need to have the fee stored in the state for the estimated execution price calculation

Note: this fee is volume aware! In the future or as follow up, we could quote a fixed USD amount for partial fills.

Copy link
Collaborator

@shoom3301 shoom3301 Jan 23, 2025

Choose a reason for hiding this comment

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

this fee is volume aware

I think it worth it to reflect this fact in the value name.
feeAmount -> feeAmountFromQuote or smth else

@alfetopito alfetopito requested review from a team January 20, 2025 15:59
Copy link
Contributor

@elena-zh elena-zh left a comment

Choose a reason for hiding this comment

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

Hey @alfetopito , thank you!

  1. But the app is crashed in this PR:
  • I connected to this account on Ethereum 0x9FA3c00a92Ec5f96B1Ad2527ab41B3932EFEDa58
  • Swap container was prefilled with selling 456 WETH per USDC
  • Then I opened Limit orders page and it crashed
    image

Also, I can catch a crash when pick a different token pair (COW/WETH as an example), and start edititng the sell amount.

  1. Also, is this OK that a price stays unchanged when I specify orders to sell different amounts for fill-or kill orders?
    image
    while SWAP container shows a liquidity-dependent price?
    image

* fix: memoize and error handle market price calculation on ExecutionPriceUpdater

* fix: error handling SpotPriceUpdater

* fix: avoid division by 0

* fix: don't be stupid and create invalid fractions

* fix: use console.error for errors instead of debug

* fix: numerator and denominator are inverted in the price constructor

* fix: skip est. exec. price display when it's 0

* fix: use est. exec. price calculated locally
* Limit price: 182000 / 100 = 1820 USDC per 1 WETH
*
* Fee with margin: 0.002 + 5% = 0.0021 WETH
* Executes at: 182000 / (100 - 0.0021) = 1820.038 USDC per 1 WETH
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for the example!
It makes it clear!

@alfetopito alfetopito merged commit e014c34 into feat/limit-ui-upgrade Jan 23, 2025
6 of 11 checks passed
@alfetopito alfetopito deleted the fix/est-exec-price branch January 23, 2025 11:41
@github-actions github-actions bot locked and limited conversation to collaborators Jan 23, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants