Skip to content

Decompiled function selector/signature #553

@0xKitsune

Description

@0xKitsune

Component

Heimdall (Core)

Describe the feature you would like

Currently when using heimdall-decompile, the decompiled ABI provides access to the function name as well as the params, return data, mutability, etc. however it would be helpful to have the function selector or signature.

I am working on a feature in amms-rs where a user can search for all AMM Factory forks (ex. all instances of UniswapV2Factory) deployed to a specific chain.

amms-rs uses the sol! macro from alloy to create Rust bindings for contract interfaces. The struct generated by the sol! macro only provides access to function selectors or signatures. It would be helpful to have access to the selector or signature from the decompiled ABI to check if the target interface matches the decompiled code. This can be constructed from the data returned but it would be nice to have out of the box.

Below is a quick example showing the difference in between the two. Here is the link to the example if you would like to run it yourself as well!

use alloy::sol_types::SolCall;
use amms::amms::uniswap_v2::IUniswapV2Factory::{self};
use heimdall_decompiler::{decompile, DecompilerArgsBuilder};

#[tokio::main]
async fn main() -> eyre::Result<()> {
    tracing_subscriber::fmt::init();
    let rpc_endpoint = std::env::var("ETHEREUM_PROVIDER")?;

    let uniswap_v2_args = DecompilerArgsBuilder::new()
        .target("0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f".to_string())
        .rpc_url(rpc_endpoint.clone())
        .build()?;

    let decompiled_abi = decompile(uniswap_v2_args).await?.abi;

    println!("Selector {:?}", IUniswapV2Factory::allPairsCall::SELECTOR);
    println!("Signature {:?}", IUniswapV2Factory::allPairsCall::SIGNATURE);

    for (k, v) in decompiled_abi.functions {
        println!("Decompiled: {:?}: {:?}", k, v);
    }

    Ok(())
}
Selector [30, 61, 209, 139]
Signature "allPairs(uint256)"

Decompiled: "allPairs": [Function { name: "allPairs", inputs: [Param { ty: "uint256", name: "arg0", components: [], internal_type: None }], outputs: [Param { ty: "uint256", name: "", components: [], internal_type: None }], state_mutability: View }]
Decompiled: "allPairsLength": [Function { name: "allPairsLength", inputs: [], outputs: [Param { ty: "uint256", name: "", components: [], internal_type: None }], state_mutability: View }]
Decompiled: "createPair": [Function { name: "createPair", inputs: [Param { ty: "address", name: "arg0", components: [], internal_type: None }, Param { ty: "address", name: "arg1", components: [], internal_type: None }], outputs: [Param { ty: "uint256", name: "", components: [], internal_type: None }], state_mutability: Payable }]
Decompiled: "feeTo": [Function { name: "feeTo", inputs: [], outputs: [Param { ty: "uint256", name: "", components: [], internal_type: None }], state_mutability: View }]
Decompiled: "feeToSetter": [Function { name: "feeToSetter", inputs: [], outputs: [Param { ty: "uint256", name: "", components: [], internal_type: None }], state_mutability: View }]
Decompiled: "getPair": [Function { name: "getPair", inputs: [Param { ty: "address", name: "arg0", components: [], internal_type: None }, Param { ty: "address", name: "arg1", components: [], internal_type: None }], outputs: [Param { ty: "uint256", name: "", components: [], internal_type: None }], state_mutability: View }]
Decompiled: "setFeeTo": [Function { name: "setFeeTo", inputs: [Param { ty: "address", name: "arg0", components: [], internal_type: None }], outputs: [], state_mutability: Payable }]
Decompiled: "setFeeToSetter": [Function { name: "setFeeToSetter", inputs: [Param { ty: "address", name: "arg0", components: [], internal_type: None }], outputs: [], state_mutability: Payable }]

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions