Skip to content

Conversation

@kaze-cow
Copy link
Contributor

@kaze-cow kaze-cow commented Dec 17, 2025

Description

One of the common nuisance cases that frequently occurs with orders is that a user (or some other protocol, whatever) transfers the balance of the token they intend to swap away after placing the order.

Rather than keeping these orders on the books, this PR introduces a new maintenance task on the autopilot which tracks all Transfer events on the blockchain, and if one matches an open order's owner and sell_token (aka, transfer of a token from an account which has an open order), we cancel the order proactively.

This change comes with some BREAKING changes that we should consider if we want or not that may affect some users (to me it makes a lot of sense, but who knows. thats what this PR is for):

  • (including LIMIT orders) would be automatically CANCELLED if any transfers from a users wallet are detected. This would occur even if the user still has sufficient balance remaining. checking to see if the user has sufficient balance remaining would likely be excessive as we already do that check in the auction process
  • though this is not how any existing processes work to my knowledge, the transfer listener assumes that the owner of the trade and the sell_token will not be transferred from the users wallet, but some processes (ex. euler) may not actually have the sell_token in the user's wallet. For these unusual cases, it should be harmless, but perhaps there is an edge case I am not thinking of.

This is not intended to be a replacement for the existing; only a measure to improve performance and reduce nuisance order propogation in aave or regular orders.

additionally issues that remain unverified that we would want to check on a shadow database or something if the performance of the DB query good enough? it uses the live_orders query from the shraed lib which we execute once per auction, and then it has the database filter using a table of potentially hundreds of pairs uploaded on the spot. I think its OK, but good to double check.

other notes:

  • this task will only run on blocks that are actively coming in, and is not intended to be used to scan logs from a historical time, as tihs is sort of an unnecessary edge case since we have other measures to remove insufficient balance orders, and scanning historical transfers would be expensive most likely.
  • the maintenance task supports excluding certain addresses from consideration as transfer events. for example, we don't care about transfers to the settlement contract or vault relayer (we know these addresses are our own protocol so its most likely the order being actually executed if anything, or another order executing). we may want to add other addresses to this list to further reduce the number of events under consideration.
  • the process currently runs as a maintenance task, which means it cannot remove orders that are no longer valid from the current auction. if we want to be able to do this before the auction starts, we should probably add it to the main run_forever loop instead.

Changes

  • create maintenance task transfer_listener for cleaning
  • add setting to enable/disable the transfer_listener
  • create e2e test verifying maintenance task effectiveness (not yet completed; pending confirmation that we wnat this feature)

How to test

I made a script for the playground that confirms this works as expected, but I did not commit it in these changes. LMK if I should add.

…hat transfer balance from their account before a swap
@MartinquaXD
Copy link
Contributor

I don't think this is an avenue we should go down. It has been discussed in the past that the protocol should do LESS filtering of orders, not more.
At most this should be an optimization on the driver side because individual drivers may chose to implement any kind of optimziations but the protocol itself should remain as impartial as possible.

That being said here are some comments on the implementation:
This cancellation logic does not take into account the actual balance that remains after the transfer. If you have 1M USDC and transfer 100 your 1K order should not be cancelled. Additionally this should take pre-hooks into account that unlock the necessary funds in the first place.

IMO this idea might be useful as a means to reduce the number of balances the driver has to update. Let's say the balancer fetching logic puts only EIP 712 orders on a timer. If the timer runs out OR if it detects such an ERC20 transfer event it will invalidate the cached balance value and refetch it.
Although even that might be too crude because balances might change at any time for rebalancing tokens. Maybe another safe guard would be to check whether the balance changed between 2 measurements triggered by a timer. If the available balance of an order changed the sell token could be considered erratic and be upgraded to updating balances on every block because we were clearly not able to fully determine when the balance of a token is expected to change.

@chase-watts
Copy link

If this only takes into account actual transfers, it would miss any orders where the balance changes due to a swap.

But if it's also detecting when swaps are made (on CoW or dexes) and canceling orders based on that, there's a lot of trading strategies that would break. The most obviously thing it would break (if taking swaps into account) is basically all partially fillable orders that get a partial fill...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants