Skip to content

Feature Request: read setPreSignature orders from the blockchain (and MEV them in a good way!!) #5577

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

Open
SecurityIsHard69420666 opened this issue Mar 29, 2025 · 5 comments

Comments

@SecurityIsHard69420666
Copy link

SecurityIsHard69420666 commented Mar 29, 2025

  1. Solvers can and should read setPreSignature orders straight from the blockchain. I don't see the point in requiring a 2nd submission to the Cow Swap Orderbook API.

  2. MEV (the good kind)! Since submitting an order with setPreSignature allows for frontrunning :(... it would be cool if the "MEV Blocker" RPC shared the "pending" setPreSignature orders with the solvers... so they could potentially put your "setPreSignature" tx and "settleOrder" tx in the same block before anybody has a chance to frontrun! 🔥 🐄

thanks for the awesome product!

edit: i'm not sure it's possible, but maybe
edit 2: i'm wondering why solvers can't just hold onto your "pending" setPreSignature tx indefinitely until the order can be solved... but i probably just don't understand something. like yea sure we're breaking the typical flow of things... but who cares :-P? p.s.: i'm using a Safe with only 1 signer, if that matters
edit3: edit2 would only work if your order was not partiallyFillable

@elena-zh
Copy link
Contributor

Hi @SecurityIsHard69420666 , thank you for the request!
We've sent it to internal review.

@MartinquaXD
Copy link

Regarding 1:
The setPreSignature() call does not contain enough information to express the intent of the order. pre-sign only acts as a "key" to indicate that whoever sent the setPreSignature() transaction authorizes the execution of an order with the respective UID. Also the setPreSignature() call does not go through the orderbook but to the blockchain.
So the flow still has to be that you first submit the full order (trade intent) to the orderbook and authorize (or "activate") it later on with an onchain transaction coming from the owner of the order.

Regarding 2:
I can see how it's possible that somebody would be able to recover the trade intent associated with an PreSign event observed onchain (will not go into the details here). However, delaying the setPreSignature() transaction also comes with problems:

  1. the owner of the order needs to call setPreSignature(). If the order owner is an EOA (i.e. an address backed by a private key and not a smart contract) the solver can not execute it for you since the call would come from the solver's account.
  2. Even for safes there are challenges. It's possible to generate a tx that anybody can execute for you that would set the presignature for your order however, the safe uses nonces internally. That means the transaction you generate will only work if the safe still has the expected nonce internally.
    Let's say your safe has nonce 12 and you create a tx that can only be executed if the safe has nonce 13. That means either you can't continue to use your safe for unrelated things or you would invalidate the presign tx because all transactions will increment the safe's internal nonce.
    You even have that problem for a safe you only use for cow swap. Let's say you create 2 setPreSignature() tx (one for nonce 13 and one for nonce 14). Due to nonce invalidation solvers would always have to execute the 13 tx first to make the 14 executable.

@SecurityIsHard69420666
Copy link
Author

SecurityIsHard69420666 commented Mar 31, 2025

Regarding 1: The setPreSignature() call does not contain enough information to express the intent of the order. pre-sign only acts as a "key" to indicate that whoever sent the setPreSignature() transaction authorizes the execution of an order with the respective UID. Also the setPreSignature() call does not go through the orderbook but to the blockchain. So the flow still has to be that you first submit the full order (trade intent) to the orderbook and authorize (or "activate") it later on with an onchain transaction coming from the owner of the order.

In my use case (Zodiac Role Modifiers) I'm calling setPreSignature indirectly through CowSwapOrderSigner, which definitely puts the full order details on the blockchain. (side note: i wonder why zodiac doesn't call setPreSignature directly :-/ (edit: it's because the zodiac contracts have to check+verify the arg conditions))

Regarding 2: I can see how it's possible that somebody would be able to recover the trade intent associated with an PreSign event observed onchain (will not go into the details here). However, delaying the setPreSignature() transaction also comes with problems:

  1. the owner of the order needs to call setPreSignature(). If the order owner is an EOA (i.e. an address backed by a private key and not a smart contract) the solver can not execute it for you since the call would come from the solver's account.

yes I'm only talking about Safe wallets. EOAs can already post orders off-chain so they don't have to worry about front-running.

  1. Even for safes there are challenges. It's possible to generate a tx that anybody can execute for you that would set the presignature for your order however, the safe uses nonces internally. That means the transaction you generate will only work if the safe still has the expected nonce internally.> Let's say your safe has nonce 12 and you create a tx that can only be executed if the safe has nonce 13. That means either you can't continue to use your safe for unrelated things or you would invalidate the presign tx because all transactions will increment the safe's internal nonce.
    You even have that problem for a safe you only use for cow swap. Let's say you create 2 setPreSignature() tx (one for nonce 13 and one for nonce 14). Due to nonce invalidation solvers would always have to execute the 13 tx first to make the 14 executable.

These are acceptable conditions for avoiding front-running imo. I'm not saying it should be the default way of doing things, but it could be something you opt into. "follow this guide ('don't continue to use your Safe when an order is pending, and your orders must be solved in the order they were received') and use this special RPC endpoint (which shares pending tx with solvers)" ---> you can't get front-run anymore :)

edit: I honestly fully admit that what I'm proposing is hacky af..... but honestly so is MEV in general.

@MartinquaXD
Copy link

Did you consider using an EIP-1271 signature instead of pre-sign? That way you can prepare the order the safe is supposed to accept, generate the necessary signature using the safe and then submit both off-chain to the orderbook. This will keep the order private until it gets executed by solvers.

@SecurityIsHard69420666
Copy link
Author

I realized that the reason I have to use Zodiac's CowSwapOrderSigner contract is to check+verify the arg conditions for the order, and to be honest I don't know if Zodiac could be used with EIP-1271... but I would imagine if it could then it already would? I'm a little out of my depth here :-P

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

No branches or pull requests

3 participants