Skip to content

add fallback and receive support including catching failing assertions#723

Merged
anishnaik merged 7 commits intomasterfrom
dev/call-fallback
Nov 26, 2025
Merged

add fallback and receive support including catching failing assertions#723
anishnaik merged 7 commits intomasterfrom
dev/call-fallback

Conversation

@tuturu-tech
Copy link
Copy Markdown
Contributor

@tuturu-tech tuturu-tech commented Nov 25, 2025

Closes #214

Summary

Add support for fuzzing fallback and receive functions in Medusa. These can now be called during fuzzing campaigns and their assertions will be properly detected and reported.

This implementation includes a comprehensive test case that validates both functions are being called correctly during fuzzing.

Changes

  • Fuzzing Coverage: Fallback and receive functions are now called with a 0.1% (1/1000) probability during fuzzing
  • Call Data Generation:
    • Fallback functions receive random call data (1-256 bytes) to ensure they're triggered
    • Receive functions use empty call data (0 bytes) via ABI encoding path
  • Test Coverage: Added TestFallbackReceiveCalling test that validates both functions are called
  • Robust Handling: Fixed edge cases in cloning, method resolution, string representation, and shrinking

Implementation Details

Files Modified

  1. fuzzing/fuzzer_worker.go

    • Added fallbackMethods list to track fallback/receive functions separately
    • Populated in updateMethods() using HasFallback() and HasReceive() checks
    • Added nil check in shrinkCallSequence() to skip shrinking for fallback/receive (which have nil DataAbiValues)
  2. fuzzing/fuzzer_worker_sequence_generator.go

    • Modified method selection logic to include fallback/receive with 1/1000 probability
    • Added branching in generateNewElement() to detect fallback functions
    • Fallback functions use NewCallMessage with random bytes (1-256 length)
    • Regular functions continue using NewCallMessageWithAbiValueData with ABI encoding
    • Receive functions use ABI encoding path which produces empty calldata (works correctly)
  3. fuzzing/calls/call_message.go

    • Fixed Clone() to handle nil DataAbiValues (occurs for fallback/receive using raw calldata)
  4. fuzzing/calls/call_sequence.go

    • Modified Method() to return fallback/receive methods when MethodById fails
    • Updated String() to display hex calldata for fallback/receive instead of unpacking args
  5. fuzzing/fuzzer_test.go (NEW)

    • Added TestFallbackReceiveCalling test function
    • Test validates both fallback and receive are called during fuzzing
  6. fuzzing/testdata/contracts/assertions/assert_fallback_receive.sol (NEW)

    • Test contract with fallback and receive functions that set boolean flags
    • Includes assertion test that fails when both functions have been called

Technical Notes

  • Fallback Detection: Uses selectedMethod.Method.Type == abi.Fallback to detect fallback functions
  • Random Calldata: make([]byte, g.worker.randomProvider.Intn(255)+1) generates 1-256 bytes
  • Receive Handling: Receive functions go through ABI encoding with empty inputs, producing 0 bytes calldata (correct behavior)
  • Method Resolution: When MethodById fails, checks for receive (empty data) first, then fallback

Why This Approach Works

  1. Fallback: Gets non-empty random data (1-256 bytes), ensuring it's called instead of receive
  2. Receive: Gets empty data through ABI encoding path, correctly matching Solidity's receive() requirements
  3. Separation: Both tracked in fallbackMethods list, selected with equal probability
  4. Testing: Comprehensive test validates both are actually called during fuzzing

Testing

  • Automated Test: TestFallbackReceiveCalling validates both fallback and receive are called
  • Test Approach: Contract with two booleans, assertion fails when both are set
  • Test Limit: 100,000 sequences

Run test:

go test -v -run TestFallbackReceiveCalling ./fuzzing/

Remaining Work

Completed ✅

- Add test case (TestFallbackReceiveCalling)
- Implement fallback/receive call data generation
- Handle edge cases (cloning, shrinking, string representation)

Optional Future Improvements

- Add explicit receive handling in generateNewElement() for code clarity
- Consider adding logging for debugging fallback/receive selection
- Add test for contracts with only fallback (no receive) and vice versa

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@anishnaik anishnaik merged commit c8a990d into master Nov 26, 2025
9 checks passed
@anishnaik anishnaik deleted the dev/call-fallback branch November 26, 2025 18:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: call fallback function

2 participants