# Zero-address and value-path reverts

Shared transfer or execution path reverts because callee rejects forwarded value or zero-address source

_Area: Smart contract access control and control flow. Seen in 3 disclosed reports; latest 2024-01-10. Updated 2026-11-02._

## How it works
A shared path forwards something the callee cannot accept: native value to a function that is not `payable` or a contract with no `receive`, or a `transferFrom` whose source is `address(0)`. The call reverts, and because the path is shared, every operation routed through it fails — not only the one that triggered the mismatch. The invariant that breaks: whatever the caller forwards (value, a transfer source) must be acceptable to the callee and to the token.

## Where it shows up
- Execution functions reached by `delegatecall` from a `payable` caller but not themselves `payable` [E1](https://bugbountylibrary.com/r/c4%3A2023-10-party%3AM-01.md)
- Governance/executor contracts that forward `value` in low-level calls but define no `receive()`/`payable` entrypoint [E3](https://bugbountylibrary.com/r/c4%3A2023-07-moonwell%3AM-09.md)
- State initialized to `address(0)` then migrated via `transferFrom`/`safeTransferFrom` from that sentinel [E2](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-29.md)
- Precondition: a token that permits burns/transfers to `address(0)`, letting anyone seed a balance there [E2](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-29.md)
- A `balanceOf(oldAddress)` read (old address possibly zero) feeding a transfer decision [E2](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-29.md)

## How to review
For each shared path, check the exact invariant: every value or transfer the caller forwards must be acceptable to the callee.
- If a function is invoked via `delegatecall` from a `payable` caller and reads `msg.value`, confirm the implementation itself is `payable` [E1](https://bugbountylibrary.com/r/c4%3A2023-10-party%3AM-01.md).
- If a contract forwards `value` in a call, confirm it can receive native tokens (`receive`/`fallback`/`payable`) and that its balance covers the value [E3](https://bugbountylibrary.com/r/c4%3A2023-07-moonwell%3AM-09.md).
- If a state variable can hold `address(0)` and is later used as a transfer source, confirm the code skips or guards the zero address, and that no token can be sent to it [E2](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-29.md).

## How finders spotted it
- Compared `executeProposal()`'s signature against `_executeArbitraryCalls()`'s use of `msg.value`; noted `delegatecall` preserves value but the callee must still be `payable` [E1](https://bugbountylibrary.com/r/c4%3A2023-10-party%3AM-01.md).
- Read `createBribeFlywheel`: saw `flywheelRewards` set to `address(0)` then reset via `setFlywheelRewards`, which transfers any existing balance from the old address without a zero check; realized the token permits burns to zero, so anyone can seed that balance [E2](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-29.md).
- Read the execute path, saw the `target.call{value:value}` forwarding, and noticed no `receive`/`payable` entrypoint; confirmed with a Foundry test [E3](https://bugbountylibrary.com/r/c4%3A2023-07-moonwell%3AM-09.md).

## Variants seen
- Missing `payable` on a `delegatecall` target blocking ETH-attached proposals [E1](https://bugbountylibrary.com/r/c4%3A2023-10-party%3AM-01.md)
- Zero-address balance migration reverting all factory creations [E2](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-29.md)
- Missing `receive`/`payable` on a governor blocking native-value proposals [E3](https://bugbountylibrary.com/r/c4%3A2023-07-moonwell%3AM-09.md)

## Impact and severity
In each case a whole class of legitimate operations is blocked: ETH-bearing proposals cannot execute [E1](https://bugbountylibrary.com/r/c4%3A2023-10-party%3AM-01.md)[E3](https://bugbountylibrary.com/r/c4%3A2023-07-moonwell%3AM-09.md), and `createBribeFlywheel` can be permanently blocked by sending 1 wei of reward token to `address(0)` [E2](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-29.md). Severity is medium: no funds are stolen, but functionality is denied, and in E2 the trigger is cheap and persistent. Impact rises when the blocked path is the only route for a core operation (proposal execution, factory creation).

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2023-10-party%3AM-01.md
- E2: https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-29.md
- E3: https://bugbountylibrary.com/r/c4%3A2023-07-moonwell%3AM-09.md
