Arbitrum Stylus logo

Stylus by Example

Fallback and Receive Functions in Stylus

In Stylus smart contracts, fallback and receive functions are special handlers for incoming transactions when no other function matches the call signature. They’re essential for flexible contracts that can handle direct Ether transfers and unknown function calls.

Understanding the Difference

Receive Function

Specifically handles plain Ether transfers—transactions that send Ether with no calldata.

Key characteristics:

  • Called when a transaction has no calldata (empty data field)
  • Takes no inputs and returns no outputs
  • Optional — if missing, plain Ether transfers will trigger the fallback
  • Has higher priority than fallback when both exist

Fallback Function

Catch-all handler for transactions that don’t match any function signature.

Key characteristics:

  • Called when no function matches the calldata
  • Also called for plain Ether transfers if receive is not defined
  • May be payable or non-payable
  • Can access calldata that was sent
  • If not defined, unmatched calls revert

Function Call Priority

When a transaction targets your contract, Stylus follows this decision tree:

  • Has calldata?

    • No → Call receive() (if defined), otherwise call fallback()
    • Yes → Try to match a function signature
  • Signature matches?

    • Yes → Call the matching function
    • No → Call fallback() (if defined), otherwise revert

Complete Working Example

This example demonstrates both functions and includes tests that verify:

  • Event emission order and payloads
  • Tracking of total Ether received
  • Counting how many times receive/fallback are invoked
  • Per-sender balance updates
  • Logging of the function selector (bytes4) when calldata is present

Notes:

  • bytes4 selector is logged as FixedBytes<4>; we derive it from the first 4 bytes of calldata.
  • When value is sent to fallback, the example emits three logs (in order): EtherReceivedFallbackTriggeredUnknownFunctionCalled.
  • When no value is sent, fallback emits two logs: FallbackTriggeredUnknownFunctionCalled.

src/lib.rs

1Loading...
1Loading...

Cargo.toml

1Loading...
1Loading...

src/main.rs

1Loading...
1Loading...