shazow / whatsabi

Extract the ABI (and resolve proxies, and get other metadata) from Ethereum bytecode, even without source code.
https://shazow.github.io/whatsabi/
MIT License
1.04k stars 71 forks source link

Improve devex for only resolving proxies #120

Closed shazow closed 1 week ago

shazow commented 1 week ago

This is mainly when a user already has bytecode and just wants to resolve proxies on it with the minimum number of RPC requests. (A valid provider is still required because various proxies require more RPC requests to resolve.)

Example:

const address = "0x...";
const bytecode = "0x..."; // Already loaded from somewhere

const cachedCodeProvider = whatsabi.providers.WithCachedCode(provider, {
  [address]: bytecode,
});

const result = whatsabi.autoload(cachedCodeProvider, address, {
  abiLoader: false, // Skip ABI loaders
  signatureLookup: false, // Skip looking up selector signatures
  followProxies: true,
})

if (result.address !== address) console.log(`Resolved proxy: ${address} -> ${result.address}`); // only if followProxies is true
if (result.proxies.length > 0) console.log("Proxies detected:", result.proxies);
// Note that some proxies can only be resolved relative to a selector, like DiamondProxy. These will need to be resolved manually via result.proxies.
kuzdogan commented 1 week ago

Is there a way to get the type of the proxy (GnosisSafe, EIP1967 etc.)?

cc: @manuelwedler

shazow commented 1 week ago

Is there a way to get the type of the proxy (GnosisSafe, EIP1967 etc.)?

Yes, if AutoloadConfig.followProxies is false (the default), then AutoloadResult.proxies is a list of proxies.ProxyResolver that were detected: https://github.com/shazow/whatsabi/blob/main/src/proxies.ts

They'll be things like GnosisSafeProxyResolver, EIP1967ProxyResolver, EIP1967ProxyResolver, etc.

I can bolt on name attributes to them if that's helpful?

Basically:

const result = whatsabi.autoload(provider, address, config);
console.log(result.proxies);
shazow commented 1 week ago

Added a name property to the proxy instances.

81:    override name = "EIP1967Proxy";
122:    override name = "DiamondProxy";
223:    override name = "ZeppelinOSProxy";
231:    override name = "PROXIABLEProxy";
241:    override name = "SequenceWalletProxy";
252:    override name = "FixedProxy";

Note that "MinimalProxy" falls into "FixedProxy" in my nomenclature, as it contains several varieties (all of which have a fixed address they resolve to in the bytecode).

shazow commented 1 week ago

Aiming to do a release next week that will include this. :)