Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

autoload: ABIFunction result sometimes missing selector (marked as required by type) #164

Open
GalloDaSballo opened this issue Jan 4, 2025 · 5 comments
Labels
bug Something isn't working soon Planned, targeting a near-future release

Comments

@GalloDaSballo
Copy link

Impact

The type declaration for AbiFunction is as follows:

export type ABIFunction = {
    type: "function"; // TODO: constructor, receive, fallback
    selector: string;
    name?: string;
    outputs?: ABIOutput[];
    inputs?: ABIInput[];
    sig?: string;
    sigAlts?: string[];
    payable?: boolean;
    stateMutability?: StateMutability;
};

Which led me to believe that you'd always get the selector

However, it seems like when whatsabi can determine the "real" abi, it will not return the selector

POC

Address is 0xF576e1f09e2eb4992d5FFDF68bec4Ea489FA417d, basically one for which the tool is able to grab the ABI correctly

async function makeRepro() {
    const result = await whatsabi.autoload(address, { provider });

    console.log("result.abi", result.abi)
    const fns: ABIFunction[] = result.abi.filter(abi => abi.type === "function") as undefined as ABIFunction[]
    console.log("result.abi", fns[0].selector)
}

makeRepro()

Logs

/// omitted
  },
  {
    inputs: [ [Object], [Object] ],
    name: 'totalUltiAllocated',
    outputs: [ [Object] ],
    stateMutability: 'view',
    type: 'function'
  },
  ... 8 more items
]
result.abi undefined

Mitigation

I believe the tool should always return the selector or the declaration should be changed to have a conditional value

@shazow shazow added bug Something isn't working soon Planned, targeting a near-future release labels Jan 4, 2025
@shazow
Copy link
Owner

shazow commented Jan 4, 2025

Good call, that's a bug!

I believe the intention was to always include the selector, but need to double check whether there's some newer callpaths where this is not practical to include the selector.

@shazow shazow changed the title Typescript types are not respected at runtime autoload: ABIFunction result sometimes missing selector (marked as required by type) Jan 4, 2025
@GalloDaSballo
Copy link
Author

Good call, that's a bug!

I believe the intention was to always include the selector, but need to double check whether there's some newer callpaths where this is not practical to include the selector.

Happy to help

From my POV the selector is very useful even though it's technically not part of the ABI spec, ideally should be kept and since you're returning the function name and inputs I'm confident you should be able to return both the funsig and the selector reliably

Whereas when the tool cannot determine inputs (the use case I was exploring), returning the selector is already very helpful

@GalloDaSballo
Copy link
Author

If I can make a request, when the tool is unable to determine inputs, even just capping the calldata length can be very useful, as I'm using this for fuzzing so clamping the length of bytes is enough for me to basically try the selector and all inputs although in a less effective fashion

@shazow
Copy link
Owner

shazow commented Jan 4, 2025

If I can make a request, when the tool is unable to determine inputs, even just capping the calldata length can be very useful, as I'm using this for fuzzing so clamping the length of bytes is enough for me to basically try the selector and all inputs although in a less effective fashion

I'm not certain this is always possible using our current approach (e.g. variable length inputs), but might be sometimes!

You could also try an opcode tracing based disassembler like https://github.com/cdump/evmole/

@GalloDaSballo
Copy link
Author

If I can make a request, when the tool is unable to determine inputs, even just capping the calldata length can be very useful, as I'm using this for fuzzing so clamping the length of bytes is enough for me to basically try the selector and all inputs although in a less effective fashion

I'm not certain this is always possible using our current approach (e.g. variable length inputs), but might be sometimes!

You could also try an opcode tracing based disassembler like https://github.com/cdump/evmole/

Thank you for the recommendation, I'm looking to use both!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working soon Planned, targeting a near-future release
Projects
None yet
Development

No branches or pull requests

2 participants