- you need foundry installed on your machine for this process, as well as having
forge-stdlib for contract dependencies, or if you have nix package manager installed you can enter the default shell where all the deps are available. - go to the
./diag/DiagOrder.solfile and modify the data with the ones you want ot diag: - add the rpc url of the evm network
- add the block number at which the debugging should take place.
- replace the
fromaddress with the transaction sender address, ie msg.sender. - replace the
toaddress with the arb contract address on the desired network. - replace the
datawith the calldata without leading 0x taken from otel (hyperdx). - save the file and now you can run the following command to get the traces:
forge script diag/DiagOrder.sol:DiagOrder -vvvvvafter the traces are printed, the desired data can be extraced. here are some examples to explain the steps required to get the desired data:
- find the
eval2()call, as it is clear in the image above, the first arrow points to the eval() being called - find the first call with
00000000selector (second arrow), that is the eval result, and it is encoded, so the first 2 words (the first 2 256bytes) determine the price and maxouput in order, which in this case are 0x0 and 0x0x43cc30c876b457. - the eval result is also available on the 3rd column of the
Contextevent, (3rd arrow with 2 following red dots, first is order maxoutput and second is order ratio) - 4th arrow determines the RP amountIn, for identifying it, you need to find the
processRoute()call, once found, its second argument determines theamountIn, in this case it is 19083333333333079, (the 4th argument also determines the min expected receiving amount from the swap set by orderbook for the call) - lastly the RP quote amountOut is visible in the last arrow, to find it, first try to find the
processRoutecall (same as last step), and from there and blow that you can find the very last event calledSwap(at times, there can be multiple depending on the route, but we are only interested in the last one, since that would indicate the last swap which is the final receiving amount), once you found that event, the very lastTransferevent before that determines the receiving transfer event of the RP swap, and itsparam2is the actual amountOut received by the swap, in this case it is 528. to make sure you are looking at the correctTransferevent, you can check the 2balanceOf()calls after theSwapevent that we mentioned previously, check those and make sure their addresses match the order's input and output token addresses, thosebalanceOfcalls are the very last calls inprocessRoutecall checking if the swap input/output are not violated. - now by having
amountInandamountOutyou can easily calculate the AMM price/ratio by dividing them and compare it against theeval()price/ratio
- this example is exactly as previous one, but it is an unsuccessfull call, so the error details are visible at the end of the traces, explaining the reason why the call failed.
- everything about identifying the eval result and RP quote is the same as previous example, but you can see that there are multiple
SwapandTransferevents, and the ones that are in our interest are the very last ones (flagged by red arrow), you can also see thebalanceOfcalls at after the specifiedSwapevent that match the order's input/output tokens. in this case the amountOut is 33388, amountIn is 27685185185185008000, and eval result is 27685185185185008000 maxoutput and 2500000000000000 price, so by dividing amountOut from amountIn we reach to about 0.0012 as the current AMM market price, which is below what the order is asking for which is 0.0025, as a result the call failed since there is no arbing opportunity in this case.
- sometimes traces dont go beyond eval, ie eval failing is the reason the call has failed, in such cases the reason of why eval has failed is clearly visible at the end of traces.
- in such cases traces wont produce the RP quote since the call has terminated before even reaching to that stage, so it is not possible to get the RP quote in such cases.
PS: these data are available elsewhere throughout the traces, so this is not the only way to extract them but seems to be the easiest one.


