Problem Statement
When developer implements receive function while fallback is already implemented, part of requests early handled by fallback are redirected to receive function.
I see this behavior as non-obvious. Developer may add a dependency which implements receive function or whatever and this might affect initial solution in a hidden way.
Details
Here is the table of which function processes request depending on receive/fallback existence and modifiers. It can be seen that receive and fallback functionalities are not complement and receive overrides fallback in case of combination.
| Value | Data | Receive | Fallback | Fallback Payable | Receive + Fallback | Receive + Fallback Payable |
|---|---|---|---|---|---|---|
| no | no | receive | fallback | fallback | receive | receive |
| no | some | revert | fallback | fallback | fallback | fallback |
| some | no | receive | revert | fallback | receive | receive |
| some | some | revert | revert | fallback | revert | fallback |
Additionally, there is a compiler warnings that propose to implement receive function if fallback payable is implemented. This is quite confusing and may lead to initial functionality break in case of receive doesn’t just copy fallback.
Proposal
From my point of view, receive/fallback should complement each other, example provided below. This lowers flexibility but strictly distinguishes responsibility area for each of the functions.
| Value | Data | Receive | Fallback | Fallback Payable | Receive + Fallback | Receive + Fallback Payable |
|---|---|---|---|---|---|---|
| no | no | receive | revert | revert | receive | receive |
| no | some | revert | fallback | fallback | fallback | fallback |
| some | no | receive | revert | revert | receive | receive |
| some | some | revert | revert | fallback | revert | fallback |
Backward Compatibility
This breaks backward compatibility, so can’t be implemented until 0.9.0.