Quoting by eth_call on a state-changing function: gas limit and revert-data pitfalls

Disclosure: I’m on the BlazePhoenix team (a pre-launch DEX aggregator). This is a general question about a pattern; I am not announcing anything.

A pattern I see in on-chain quoters is to write the quote logic as an ordinary external function (not view, because it calls into venues that are not guaranteed to be view) and have off-chain code run it through eth_call. The result is returned as normal return data, or sometimes deliberately encoded into revert data, so that the state changes are discarded.

I would like to compare notes on three practical points and hear what others have settled on.

  1. Gas limit of the simulated call. eth_call takes the node’s default gas cap unless the caller sets one, and providers differ. A quote that walks several venues can pass on one provider and fail with out-of-gas on another. Do you bound the work inside the quoter (a fixed number of venues or hops) so the worst case is known, or do you rely on the caller to pass an explicit gas value?

  2. Revert data as a return channel. Returning a result via revert with ABI-encoded data is convenient, but a genuine failure inside a venue also produces revert data. How do you keep the two distinguishable in the caller? A selector prefix on the success payload is one option; I am interested in whether people use something else.

  3. Divergence between simulation and execution. A quote computed at block N can differ from execution at block N+k. The only protection I trust is a minimum-output check inside the executing transaction. Is there any pattern where the quoter and the executor share the same code path, so the number the caller reads is produced by the same computation that later runs?

I am deliberately not including any project code here. If a compact reproduction of the revert-data question would help, I can write one as a follow-up in this thread.

Thanks for the post.

I moved it to the “code wizards” category instead, since it fits better there.

I’ve not used or seen this pattern before myself, so I’ll refrain from answering, but if you have a link to a concrete project that does this or could share a code snippet, it would be great.