foundry-rs / foundry

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.
https://getfoundry.sh
Apache License 2.0
8.28k stars 1.75k forks source link

`cast run` does not decode calldata for library (delegate-)call. #5950

Open ckoopmann opened 1 year ago

ckoopmann commented 1 year ago

Component

Cast

Have you ensured that all of these are up to date?

What version of Foundry are you on?

cast 0.2.0 (96ab913 2023-09-28T00:20:52.150553000Z)

What command(s) is the bug in?

cast run

Operating System

macOS (Apple Silicon)

Describe the bug

When running cast run on a transaction that includes delegatecalls to a library deployment, those calls are not decoded correctly in the transaction traces, even though the libraries source code is verified on etherscan.

When running cast run --rpc-url <ETH_MAINNET_RPC_URL> --quick 0x07a6ad95d76f4c1318d38564439347b39a47b126a7cbd3fe0b58a980392d4a35 the delegate calls are shown as:

image

Whereas I'd expect them to be decoded using the library's abi. (In above case it would be the swapExactTokensForTokens(DEXAdapter.Addresses,uint256,uint256,DEXAdapter.SwapData) selector.

Note that I haven't verified this behaviour for other library deployments yet, so it could be caused by something in this specific signature / example as well.

ckoopmann commented 1 year ago

Just noted that for libraries (or at least this specific one) etherscan does not show any external / public "write functions" even though there are "external" functions defined in the source code.

Maybe this is expected behaviour since this library is not meant to be called except for delegatecalls.

However it would be great to find a workaround for this on the cast side, since it currently kind of breaks the tx debug workflow by requiring users to manually decode these calls using cast abi-decode or similar tools.

image image
ckoopmann commented 1 year ago

Etherscan api also does not include these methods in the abi returned by the api, so probably non-trivial to find a workaround for this.

https://api.etherscan.io/api
   ?module=contract
   &action=getabi
   &address=0xBb02bCCE1bdcc0b07E7870346D8b2ad9397D0fAC
   &apikey=<YOUR_ETHERSCAN_API_KEY>
image
ckoopmann commented 1 year ago

For anyone facing the same issue, the manual workaround I did is:

  1. Copy calldata from trace (everything inside the brackets)
  2. Determine the called function signature by using solc --hashes and comparing the resulting output to the hash shown in the trace
  3. Decode calldata using cast and the function signature: cast abi-decode --input "swapExactTokensForTokens((address,address,address,address,address,address,address),uint256,uint256,(address[],uint24[],address,uint8))" <CALLDATA>

This is a bit of a pain though (especially step 2) and took me > 1 hour to get right, so definetely would be great to find a workaround inside cast for this.

ckoopmann commented 1 year ago

After revisiting this I noticed that we seem to use exclusively the openchain api to decode all traces. (and not from etherscan). This api does not seem to contain signatures for library functions, meaning in the above example the following query: https://api.openchain.xyz/signature-database/v1/lookup?function=0x1aafa9d8

Returns {"ok":true,"result":{"event":{},"function":{"0x1aafa9d8":null}}} which then results in the trace not being decoded.

ckoopmann commented 1 year ago

Opened an issue on openchain repo to see if their service can be extended to be able to decode these types of signatures: https://github.com/openchainxyz/openchain-monorepo/issues/21

zerosnacks commented 4 months ago

Able to reproduce with given setup

For future reference

0xBb02bCCE1bdcc0b07E7870346D8b2ad9397D0fAC::1aafa9d8(0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab60000000000000000000000000000000022d53366457f9d5e68ec105046fc4383000000000000000000000000c1db00a8e5ef7bfa476395cdbcc98235477cde4e000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000154e02c00000000000000000000000000000000000000000000000031548ccf80b0c0f90000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000030000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000000000000000001f4) [delegatecall]